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.
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.
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.
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.
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.
The default behaviour of Sun "server" HotSpot is to enlarge the heap rather than clearing SoftReference
s (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.
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
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.