views:

4179

answers:

6

My application is running on Windows Server 2000. The memory usage keeps growing (from 145m).

Is that normal? I am new to Java. The version is Tomcat5.5.

A: 

This is not normal, and is probably indicative of a memory leak.

You should try using a memory profiler to see where your application is leaking.

In general, you should be looking for loops or repeated operations where objects are created but not disposed of correctly.

Geoffrey Chetwood
This is normal for the server JVM.
sjbotha
@sjbotha: Continuous growth is definitely /not/ normal.
Geoffrey Chetwood
I think it depends if it is continual growth without any bounds or not
matt b
http://en.wiktionary.org/wiki/continual
Geoffrey Chetwood
A: 

You may have a memory leak. I would first connect jconsole to your application to determine if it is permgen space or just heap memory and then proceed to figure out where the leak is. Can you give us some more information? What is going on in your application as the memory grows?

If you are relatively new to diagnosing this kind of problem, I would recommend jprofiler. You can download a fully functional trial version and take memory snapshots to see what objects are in memory. You can use this information to figure out which objects are the source of the leak.

neesh
This app has run for years. Recently, I found this issue, because the website is running very slow. I am wondering if someone changed the configuration. I don't think there is a memory leak since nobody changes the codes.
+7  A: 

If it only ever grows, then that's a memory leak. But if it grows up to your max heap, then drops, then that is normal garbage collection behavior. There are many tools you can use to learn more. One of the simplest is to connect with JConsole (part of the JDK) and observe your heap over time.

You can also look at garbage collection information with various switches and parameters like -verbose:gc to start with.

If you want to diagnose memory leaks, there are a number of excellent tools available, including several free ones that work with Eclipse, NetBeans, IntelliJ, etc.

Alex Miller
+3  A: 

The default behaviour of Sun "server" HotSpot is to enlarge the heap rather than clearing SoftReferences (used for caches). The default was to keep them for one second for every megabyte of maximum heap size available. So, expect the heap to grow to the maximum size. If you do actually run out of memory with OutOfMemoryException or performance becomes poor (due to excessive GC or small caches), then you need to look for memory leaks.

Also Tomcat servers often suffer from memory leaks after reloading applications. For instance, Tomcat shares threads between all applications, which often causes Sun's ThreadLocal implementation to improperly retain values.

Tom Hawtin - tackline
Tomcat doesn't leak unless the applications leaves threads behind or install hooks in the VM.
Aaron Digulla
Happens a lot with certain frameworks, silly ClassLoaders...
wds
I'll edit qualify my statement a bit. The Sun ThreadLocal implementation, for instance, typically leads to leaks as Tomcat does not discard threads. I don't know what crazybob's Harmony implementation does.
Tom Hawtin - tackline
+4  A: 

IMO Tom Hawtin's answer is the best. It grows until it hits the max, then runs GC. In a server environment this makes sense: You want the best performance, not best memory usage. You pre-calculate the total amount of memory, then give each app a maximum and then everything fits and has the best performance. This behavior can be tweaked.

Use jconsole to look at how much is really being used. Do GC and watch what it goes down to. That number should not grow over time or you have a memory leak. Use visualvm to debug a memory leak.

Each time you reload an application it uses additional Perm Gen memory which cannot be reclaimed (in Sun JVM, others like JRockit don't have this problem). In production you shouldn't be reloading the app. Restart Tomcat each time. If you really want to keep doing it then you can increase the max memory and also increase the Max Perm Gen memory with the flag -XX:MaxPermSize=256m

sjbotha
MaxPermSize turned out to be exactly my problem. We were constantly deploying updated versions of the application during development.
Matthew Blackford
+1  A: 

With the program Lambda Probe you can easily look at the memory usage in Tomcat. (option System information - Memory utilization). You can see in a graph Survivor Space Perm Gen Tenured Gen Eden Space Code Cache

Just deploy this warfile to tomcat and set the startup option -Dcom.sun.management.jmxremote to the Java startup.

Now you can see what part of the memory grows.

Edwin