Jevgeni,<div><br></div><div>The best long term solution for the VM is <a href="http://en.wikipedia.org/wiki/Ephemeron">ephemerons</a>. They're not slated for Java 7 or even 8 yet though.</div><div><br></div><div>I implemented "class loader locals" as a library years ago. Unfortunately, I don't have the code anymore because I didn't end up using them.</div>
<div><br></div><div>The internals went something like this:</div><div><br></div><div>public class ClassLoaderLocals {</div><div>  public static final Map values = new ConcurrenHashMap(); </div><div>}</div><div><br></div><div>
(I used synchronization at the time.)</div><div><br></div><div>Now, force each ClassLoader to load its own copy of ClassLoaderLocals. If you reflectively invoke defineClass() instead of calling loadClass(), the ClassLoader won't check its parent loader for ClassLoaderLocals.</div>
<div><br></div><div>Finally, paper over this with a nice, ThreadLocal-like API that hides the ugly reflection.</div><div><br></div><div>Bob</div><div><br><div class="gmail_quote">On Thu, Sep 16, 2010 at 7:56 AM, Jevgeni Kabanov <span dir="ltr"><<a href="mailto:ekabanov@gmail.com">ekabanov@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div style="word-wrap:break-word">Hi guys,<div><br></div><div>I'd like to contribute two new classes to the JDK7 and add a new package-visible field to the ClassLoader. These classes would be meant for the framework and server developers to allow for greater control over the references between classes in different class loaders. Specifically the goal would be to prevent the notoriously common classloader leaks. The motivation is partially described here:</div>
<div><a href="http://dow.ngra.de/2009/06/15/classloaderlocal-how-to-avoid-classloader-leaks-on-application-redeploy/" target="_blank">http://dow.ngra.de/2009/06/15/classloaderlocal-how-to-avoid-classloader-leaks-on-application-redeploy/</a></div>
<div>That blog post also describes a way to backport it to older Java versions, unfortunately we found that the described approach will not work in some esoteric cases.</div><div><br></div><div>The pseudo-code follows. It's not really optimized or even tested and is only meant to illustrate the functionality and complexity of the proposal. I'd like to hear your feedback on this.</div>
<div><br></div><div><div>class ClassLoader {</div><div>  Map localMap = new HashMap();</div><div>  //...</div><div>}</div><div><br></div><div>public class ClassLoaderLocal {</div><div>  private Object key = new Object();</div>
<div> </div><div>  public Object get(ClassLoader cl) {</div><div>    cl.localMap.get(key);</div><div>  }</div><div> </div><div>  public void set(ClassLoader cl, Object value) {</div><div>    cl.localMap.put(key, value);</div>
<div>  }</div><div>}</div><div><br></div><div>public class ClassLoaderWeakReference extends Reference {</div><div>  private final WeakReference clRef;</div><div>  private final ClassLoaderLocal cll = new ClassLoaderLocal();</div>
<div>  public ClassLoaderWeakReference(Object target) {</div><div>     clRef = new WeakReference(target.getClass().getClassLoader());</div><div>     cll.set(target.getClass().getClassLoader(), target);</div><div>  }</div>
<div>  </div><div>  public Object get() {</div><div>    if (clRef.get() == null) </div><div>      return null;</div><div>    return cll.get((ClassLoader) clRef.get());</div><div>  }</div><div>}</div><div>
<span style="line-height:18px"><br></span><img height="54" width="54" alt="me" style="float:left;padding-top:0px;padding-right:6px;padding-bottom:0pt;padding-left:0pt;line-height:18px"><span style="line-height:18px"><strong style="color:rgb(107, 168, 23)">Jevgeni Kabanov</strong></span><span style="line-height:18px">: Founder & CTO at</span><span style="line-height:18px"><span> </span></span><span style="line-height:18px"><a href="http:/www.zeroturnaround.com/" style="color:rgb(107, 168, 23);text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(107, 168, 23)" target="_blank">ZeroTurnaround</a></span><span style="line-height:18px"><br>
</span><span style="line-height:18px"><a href="mailto:jevgeni@zeroturnaround.com" style="color:rgb(107, 168, 23);text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(107, 168, 23)" target="_blank">jevgeni@zeroturnaround.com</a></span><span style="line-height:18px"><span> </span></span><span style="line-height:18px">|</span><span style="line-height:18px"><span> </span></span><span style="line-height:18px"><a style="color:rgb(107, 168, 23);text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(107, 168, 23)">Skype: ekabanov</a></span><span style="line-height:18px"><span> </span></span><span style="line-height:18px">|</span><span style="line-height:18px"><span> </span></span><span style="line-height:18px"><a href="http://twitter.com/ekabanov" style="color:rgb(107, 168, 23);text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(107, 168, 23)" target="_blank">http://twitter.com/ekabanov</a></span><span style="line-height:18px"><br>
</span><span style="line-height:18px">"jrebel is r0x: <a href="http://bit.ly/6fRGji" target="_blank">http://bit.ly/6fRGji</a>" -</span><span style="line-height:18px"><span> </span></span><span style="line-height:18px"><a href="http://twitter.com/mschambeck" style="color:rgb(107, 168, 23);text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(107, 168, 23)" target="_blank">mschambeck</a></span>
</div>
<br></div></div></blockquote></div><br></div>