title: Classloader is not garbage collected, even without GC roots
body: <p>We have a complex application running under Glassfish V2.1.1. In order to be able to load our code dynamically, we have implemented a CustomClassloader which is able to redefine classes.
  The behaviour is quite easy: when a dynamically loaded class has change, the current instance of the CustomClassloader is "dropped" and a new one is create to redefine the needed classes.</p>
  
  <p>This works well except that after a few number of time the same class has been reloaded (hence each time a new CustomClassloader is created), we get a PermGen space error because the other instances of CustomClassloader are not garbage collected. (There should be only one single instance of this class)</p>
  
  <p>I tried different methods to track down where the leak is:</p>
  
  <ol>
  <li><a href="http://visualvm.java.net/" rel="noreferrer">visualvm</a> => I make a heap dump and extract all the instances of the CustomClassloader. I can see that none of them have been finalized. When I check for the nearest GC root, visualvm tells me that there is none (except for the last instance, because it is the 'real' used one).</li>
  <li><a href="http://docs.oracle.com/javase/6/docs/technotes/tools/share/jhat.html" rel="noreferrer">jmap/jhat</a> => It gives me almost the same result: I see all the instances of CustomClassloader and then when I click on the link to see where are the references on one of them, I get a blank page meaning there is none...</li>
  <li><a href="http://www.eclipse.org/mat/" rel="noreferrer">Eclipse Memory Analyzer Tool</a> => I get a strange result when I run the following OQL query:
  <code>SELECT c FROM INSTANCEOF my.package.CustomClassloader c</code>
  There is only one result, indicating there is only one single instance which is obviously <em>not</em> correct.</li>
  </ol>
  
  <p>I also checked this <a href="http://victor-jan.blogspot.ch/2010/05/memory-leaks-where-classloader-cannot.html" rel="noreferrer">link</a> and implemented some resources release when a new CustomClassloader is created, but nothing changes: the PermGen memory is still increasing.</p>
  
  <p>So I'm probably missing something and the difference between points (1-2) and (3) shows something I do not understand. Where can I look to get an idea of what's wrong ?
  Since all the tutorials I followed show how to search the leaking references by using the "Search nearest GC root" feature (and in my case there is none), I don't know how I can track the error.</p>
  
  <p>EDIT 1: I uploaded an example of the heap dump <a href="http://dev.sai-erp.net/nogcroot.hprof.zip" rel="noreferrer">here</a>. The ClassLoader not being unloaded can be selected in visualvm with the following query: <code>select s from saierp.core.framework.system.SAITaskClassLoader s</code>
  One can see that there are 4 instances and the three first should have been collected because there is no GC root... There must be a reference somewhere but I don't know how I can search for it. Any hint is welcomed :)</p>
  
  <p>EDIT 2: After some deeper tests I see a very strange pattern. The leak seems to depend on the data that are being loaded by OpenJPA: if no new data is loaded, then the classloader can be GCed, otherwise it is not. Here is the code I use when a create a new SAITaskClassLoader to 'clear' the old one:</p>
  
  <pre class="lang-java prettyprint-override"><code>PCRegistry.deRegister(cl);
  LogFactory.release(cl);
  ResourceBundle.clearCache(cl);
  Introspector.flushCaches();
  </code></pre>
  
  <p>= Pattern 1 (Classloader is GCed): =</p>
  
  <ol>
  <li>New SAITaskClassLoader</li>
  <li>Load Data D1, D2, ..., Dn</li>
  <li>New SAITaskClassLoader</li>
  <li>Load Data D1, D2, ..., Dn</li>
  <li>...</li>
  </ol>
  
  <p><img src="https://i.stack.imgur.com/kZj7j.png" alt="cl-gc"></p>
  
  <p>= Pattern 2 (Classloader is NOT GCed): =</p>
  
  <ol>
  <li>New SAITaskClassLoader</li>
  <li>Load Data D1, D2, D3</li>
  <li>New SAITaskClassLoader</li>
  <li>Load Data D3, D4, D5</li>
  <li>New SAITaskClassLoader</li>
  <li>Load Data D5, D6, D7</li>
  <li>...</li>
  </ol>
  
  <p><img src="https://i.stack.imgur.com/OnjLw.png" alt="cl-nogc"></p>
  
  <p>In all cases, the SAITaskClassLoader that have been cleared have no GC root. We are using OpenJPA 1.2.1.</p>
  
  <p>Thanks &amp; Best regards</p>