Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

permgen, but Java VisualVM says "No GC root found"

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.

like image 241
kmansoor Avatar asked Jun 13 '13 20:06

kmansoor


1 Answers

With all the tutorials out on the web, showing the exact process you describe,

  1. use VisualVM,
  2. search for WebappClassLoader,
  3. look for ones with 'started' equal to false.
  4. 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

visualVM showing link to compute retained sizes

After a bit(depending on the total size of your heap) this will show something like the following

visualVM showing retained sizes

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.

like image 85
muttonUp Avatar answered Sep 28 '22 02:09

muttonUp