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,
- use VisualVM,
- search for WebappClassLoader,
- look for ones with 'started' equal to false.
- Click 'Show nearest GC Root'
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.
Try closing the javaw.exe from the Task Manager processes.
来源:https://stackoverflow.com/questions/17096112/permgen-but-java-visualvm-says-no-gc-root-found