I have a very simple 'Hello world' type web application (Spring 3.2.1, Hibernate 4.1.9) on stopping/restarting the web-app Tomcat 7.0.26
The following web applications were stopped (reloaded, undeployed), but their
classes from previous runs are still loaded in memory, thus causing a memory
leak (use a profiler to confirm):
/myapp
I took the following steps: Started JVisualVM Right click on Tomcat and selected 'Heap Dump' Clicked on 'OQL Console' on the [heapdump] Ran this query:
select x from org.apache.catalina.loader.WebappClassLoader x
Found 4 instances of:
org.apache.catalina.loader.WebappClassLoader
Selected one whose "started" field was "false" Right clicked on the "this" reference and clicked "Show Nearest GC Root" A dialog saying "No GC root found" is shown.
What am I missing? any help will be greatly appreciated. Thanks.
With all the tutorials out on the web, showing the exact process you describe,
It can be confusing when it returns 'No GC Root'.
But this is a good thing
Those tutorials have missed a step, when viewing the list of WebappClassLoader click on the link 'Compute Retained Size' on the right hand side
After a bit(depending on the total size of your heap) this will show something like the following
The lines with a Retained value of 0 are also the ClassLoaders that have a status of false and no GC Root.
This just means they are ready for the next GC run that the JVM runs.
Summary : Even though 'tomcat leak Detection' shows the leak, if the retained size is 0, it hasn't leaked, its just waiting for GC to remove it.
Note : triggering a GC in visualVM will not always remove it. Although it will be removed by a GC triggered by the JVM itself.
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