I have a web application that uses hibernate 3.6.4 and spring 3.2.4 (mvc,tx and security) and is running in tomcat 7. Each time when I deploy a newer version of my app without restarting tomcat, then the memory used by tomcat increases about 50MB.
I created some heap dumps and analysed them with Eclipse Memory Analyser. I found out that each time when I redeployed the app, a new instance of WebappClassLoader was created. But even after I stopped the application with tomcat manager, the WebappClassLoader remains in memory and is not garbage collected. So after each redeploy an additional WebappClassLoader remains in memory and uses about 50MB of memory.
I used the Eclipse Memory Analyser in order to find the reference paths from the WebappClassLoader to the GC roots. In the result I couldn't find any strong references that could prevent the WebappClassLoaders from being garbage collected.
So, what keeps the WebappClassLoaders alive? Where else could I investigate in order to find out, what prevents the WebappClassLoader from the garbage collection?
I thought that there is maybe a blocking finalize() method that prevents the GC from finishing the garbage collection. But how could I check this?
A Memory Leak is a situation where there are objects present in the heap that are no longer used, but the garbage collector is unable to remove them from memory, and therefore, they're unnecessarily maintained. A memory leak is bad because it blocks memory resources and degrades system performance over time.
Use reference objects to avoid memory leaks Using the java. lang. ref package, you can work with the garbage collector in your program. This allows you to avoid directly referencing objects and use special reference objects that the garbage collector easily clears.
There might be situations where an application creates lots of objects and does not use them. Just because every objects has valid references, garbage collector in Java can't destroys the objects. Such types of useless objects are called as Memory leaks.
Memory leaks are a common error in programming, especially when using languages that have no built in automatic garbage collection, such as C and C++. Typically, a memory leak occurs because dynamically allocated memory has become unreachable.
Class loaders are in theory garbage collected when there is not reference to the object instances and class unloading is not necessary, but in practice it seems like to be more problematic.
I would recommend to read this two articles
http://frankkieviet.blogspot.com.au/2006/10/classloader-leaks-dreaded-permgen-space.html
http://frankkieviet.blogspot.com.au/2006/10/how-to-fix-dreaded-permgen-space.html
You can follow the steps presented in Anatomy of a PermGen Memory Leak tutorial too. They are using Java Visual VM but the steps and the things to check should be the same in Eclipse Memory Analizer too. In this presentation you can find the possible causes of such leaks.
Also note that if you don't see any references to WebappClassLoaders
it could be that the JVM
has plenty of PermGen
and is postponing the eviction. You could easily check this by running with a smaller PermGen
size and do a couple of redeploys.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With