<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: ClassLoaderLocal: How to avoid ClassLoader leaks on application redeploy</title>
	<atom:link href="http://dow.ngra.de/2009/06/15/classloaderlocal-how-to-avoid-classloader-leaks-on-application-redeploy/feed/" rel="self" type="application/rss+xml" />
	<link>http://dow.ngra.de/2009/06/15/classloaderlocal-how-to-avoid-classloader-leaks-on-application-redeploy/</link>
	<description>no buzzwords allowed</description>
	<lastBuildDate>Wed, 24 Feb 2010 09:44:02 -0500</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Jevgeni Kabanov</title>
		<link>http://dow.ngra.de/2009/06/15/classloaderlocal-how-to-avoid-classloader-leaks-on-application-redeploy/comment-page-1/#comment-14516</link>
		<dc:creator>Jevgeni Kabanov</dc:creator>
		<pubDate>Tue, 23 Jun 2009 07:29:08 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=926#comment-14516</guid>
		<description>@Dmitri

I use Eclipse Memory Analyzer, but tools only get you so far. You just have to understand very well how the machinery works :( That said in many cases EMA leak suspects will reveal the leaks right away.</description>
		<content:encoded><![CDATA[<p>@Dmitri</p>
<p>I use Eclipse Memory Analyzer, but tools only get you so far. You just have to understand very well how the machinery works :( That said in many cases EMA leak suspects will reveal the leaks right away.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dmitri</title>
		<link>http://dow.ngra.de/2009/06/15/classloaderlocal-how-to-avoid-classloader-leaks-on-application-redeploy/comment-page-1/#comment-14456</link>
		<dc:creator>Dmitri</dc:creator>
		<pubDate>Mon, 22 Jun 2009 10:12:00 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=926#comment-14456</guid>
		<description>Any good ideas on how to find the offenders? 

I have a 100M+ EAR application that apparently leaks classloaders. So far I&#039;ve been able to trace some of the live objects up to the static fields in one app class, but I can&#039;t find out who leaks the classloader.</description>
		<content:encoded><![CDATA[<p>Any good ideas on how to find the offenders? </p>
<p>I have a 100M+ EAR application that apparently leaks classloaders. So far I&#8217;ve been able to trace some of the live objects up to the static fields in one app class, but I can&#8217;t find out who leaks the classloader.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jevgeni Kabanov</title>
		<link>http://dow.ngra.de/2009/06/15/classloaderlocal-how-to-avoid-classloader-leaks-on-application-redeploy/comment-page-1/#comment-14106</link>
		<dc:creator>Jevgeni Kabanov</dc:creator>
		<pubDate>Wed, 17 Jun 2009 08:04:43 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=926#comment-14106</guid>
		<description>@Matt 

Thanks for the catch!</description>
		<content:encoded><![CDATA[<p>@Matt </p>
<p>Thanks for the catch!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jevgeni Kabanov</title>
		<link>http://dow.ngra.de/2009/06/15/classloaderlocal-how-to-avoid-classloader-leaks-on-application-redeploy/comment-page-1/#comment-14105</link>
		<dc:creator>Jevgeni Kabanov</dc:creator>
		<pubDate>Wed, 17 Jun 2009 07:41:40 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=926#comment-14105</guid>
		<description>@Onne 

Yeah and I guess I am too practical. Truth is even if the spec is OK for that particular class JVMs implement the spec differently and I just wouldn&#039;t risk with fine lines like that when it can lead to an error on some Sun JVM 1.4_07.</description>
		<content:encoded><![CDATA[<p>@Onne </p>
<p>Yeah and I guess I am too practical. Truth is even if the spec is OK for that particular class JVMs implement the spec differently and I just wouldn&#8217;t risk with fine lines like that when it can lead to an error on some Sun JVM 1.4_07.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matt Drees</title>
		<link>http://dow.ngra.de/2009/06/15/classloaderlocal-how-to-avoid-classloader-leaks-on-application-redeploy/comment-page-1/#comment-14092</link>
		<dc:creator>Matt Drees</dc:creator>
		<pubDate>Wed, 17 Jun 2009 02:44:19 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=926#comment-14092</guid>
		<description>FWIW, I think you need some form of synchronization in ClassLoaderLocalMap.nextHolderName().  I&#039;m pretty sure an increment operation isn&#039;t atomic, even on volatile fields.  ( See http://tech.puredanger.com/2009/01/30/java-concurrency-bugs-atomic/ )

Thanks for the post!</description>
		<content:encoded><![CDATA[<p>FWIW, I think you need some form of synchronization in ClassLoaderLocalMap.nextHolderName().  I&#8217;m pretty sure an increment operation isn&#8217;t atomic, even on volatile fields.  ( See <a href="http://tech.puredanger.com/2009/01/30/java-concurrency-bugs-atomic/" rel="nofollow">http://tech.puredanger.com/2009/01/30/java-concurrency-bugs-atomic/</a> )</p>
<p>Thanks for the post!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jevgeni Kabanov</title>
		<link>http://dow.ngra.de/2009/06/15/classloaderlocal-how-to-avoid-classloader-leaks-on-application-redeploy/comment-page-1/#comment-14059</link>
		<dc:creator>Jevgeni Kabanov</dc:creator>
		<pubDate>Tue, 16 Jun 2009 15:21:57 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=926#comment-14059</guid>
		<description>@Onne

I don&#039;t mind at all. But let&#039;s discuss this or other stuff further with some kind of beverage at hand :)</description>
		<content:encoded><![CDATA[<p>@Onne</p>
<p>I don&#8217;t mind at all. But let&#8217;s discuss this or other stuff further with some kind of beverage at hand :)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Onne</title>
		<link>http://dow.ngra.de/2009/06/15/classloaderlocal-how-to-avoid-classloader-leaks-on-application-redeploy/comment-page-1/#comment-14058</link>
		<dc:creator>Onne</dc:creator>
		<pubDate>Tue, 16 Jun 2009 15:00:28 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=926#comment-14058</guid>
		<description>The spec is quite clear, and the Holder class is not violating the rules *exactly* because it does not introduce unresolvable constrains.

The only constraint it introduces is: Holder.class.getClass().classLoader().loadClass(&quot;java.util.ArrayList&quot;) == this.getClass().classLoader().loadClass(&quot;java.util.ArrayList&quot;);

which it is ... you cannot disagree with it since it is not a beauty thing, you can disagree only if you find a counter example, which I believe is you cannot do (but would love to see one).

If &quot;defining same named class in non-sibling class loaders is not allowed&quot;, I guess it would say so in the spec, wouldn&#039;t it?

(It actually does introduce more constrains, namely on Class and String and likely some more ... since Object introduces those)

As a matter of fact, you can easily create a fun ClassCastException:

    Holder x = (Holder) loadedHolder.newInstance();

It says: cannot cast Holder to Holder ... yay!

---

I understand you were trying to fix a classloader leak, but the underlying cause for the leak is more general, and cannot be fixed in the Observable implementation, since you cannot generally know the target of a Listener and &#039;fix a strong reference&#039; (If you could, java would have a fourth Reference type: the BoundReference; as long as that thing is alive, keep the target of the BoundReference alive.)

Only in this specific case we can, since we don&#039;t fix it to the target, but to the classloader of both Listener and target. And in this case, that is good enough.

It can be fixed in general, however, if we modify the expectations of Observable slightly: namely registering something to Observable does not introduce strong a reference to that something.

(But again, I do understand that likely this is useless to you, since in the real world, you have real Observable&#039;s and their semantics cannot be changed anymore... and because of that, your proposed solution is actually quite nice.)


Well, love to see a counter example, but otherwise I&#039;ll stop harassing you :) hope you didn&#039;t mind ...</description>
		<content:encoded><![CDATA[<p>The spec is quite clear, and the Holder class is not violating the rules *exactly* because it does not introduce unresolvable constrains.</p>
<p>The only constraint it introduces is: Holder.class.getClass().classLoader().loadClass(&#8220;java.util.ArrayList&#8221;) == this.getClass().classLoader().loadClass(&#8220;java.util.ArrayList&#8221;);</p>
<p>which it is &#8230; you cannot disagree with it since it is not a beauty thing, you can disagree only if you find a counter example, which I believe is you cannot do (but would love to see one).</p>
<p>If &#8220;defining same named class in non-sibling class loaders is not allowed&#8221;, I guess it would say so in the spec, wouldn&#8217;t it?</p>
<p>(It actually does introduce more constrains, namely on Class and String and likely some more &#8230; since Object introduces those)</p>
<p>As a matter of fact, you can easily create a fun ClassCastException:</p>
<p>    Holder x = (Holder) loadedHolder.newInstance();</p>
<p>It says: cannot cast Holder to Holder &#8230; yay!</p>
<p>&#8212;</p>
<p>I understand you were trying to fix a classloader leak, but the underlying cause for the leak is more general, and cannot be fixed in the Observable implementation, since you cannot generally know the target of a Listener and &#8216;fix a strong reference&#8217; (If you could, java would have a fourth Reference type: the BoundReference; as long as that thing is alive, keep the target of the BoundReference alive.)</p>
<p>Only in this specific case we can, since we don&#8217;t fix it to the target, but to the classloader of both Listener and target. And in this case, that is good enough.</p>
<p>It can be fixed in general, however, if we modify the expectations of Observable slightly: namely registering something to Observable does not introduce strong a reference to that something.</p>
<p>(But again, I do understand that likely this is useless to you, since in the real world, you have real Observable&#8217;s and their semantics cannot be changed anymore&#8230; and because of that, your proposed solution is actually quite nice.)</p>
<p>Well, love to see a counter example, but otherwise I&#8217;ll stop harassing you :) hope you didn&#8217;t mind &#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jevgeni Kabanov</title>
		<link>http://dow.ngra.de/2009/06/15/classloaderlocal-how-to-avoid-classloader-leaks-on-application-redeploy/comment-page-1/#comment-14050</link>
		<dc:creator>Jevgeni Kabanov</dc:creator>
		<pubDate>Tue, 16 Jun 2009 13:12:11 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=926#comment-14050</guid>
		<description>1) I disagree :) Unfortunately the spec doesn&#039;t state it clear enough, but AFAIK defining same named class in non-sibling class loaders is not allowed. Checking section 4 of the original paper referred in the spec (http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.77.6898&amp;rep=rep1&amp;type=pdf), it&#039;s clear that you don&#039;t get an error only because you don&#039;t actually do anything useful with the class that would generate reasonable constraints. I think I&#039;ll leave it at that.
2) True.

I was trying to solve a particular problem of class loader leaking in Java EE, not every memory leak in the Java language. The example you bring doesn&#039;t involve any class loaders and isn&#039;t relevant :)</description>
		<content:encoded><![CDATA[<p>1) I disagree :) Unfortunately the spec doesn&#8217;t state it clear enough, but AFAIK defining same named class in non-sibling class loaders is not allowed. Checking section 4 of the original paper referred in the spec (<a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.77.6898&#038;rep=rep1&#038;type=pdf" rel="nofollow">http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.77.6898&#038;rep=rep1&#038;type=pdf</a>), it&#8217;s clear that you don&#8217;t get an error only because you don&#8217;t actually do anything useful with the class that would generate reasonable constraints. I think I&#8217;ll leave it at that.<br />
2) True.</p>
<p>I was trying to solve a particular problem of class loader leaking in Java EE, not every memory leak in the Java language. The example you bring doesn&#8217;t involve any class loaders and isn&#8217;t relevant :)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Onne</title>
		<link>http://dow.ngra.de/2009/06/15/classloaderlocal-how-to-avoid-classloader-leaks-on-application-redeploy/comment-page-1/#comment-14049</link>
		<dc:creator>Onne</dc:creator>
		<pubDate>Tue, 16 Jun 2009 12:58:26 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=926#comment-14049</guid>
		<description>@Jevgeni Kabanov

1. It does not violate the spec, since the last two of the four condition for link failure are not met.

2. My solution does not depend on loadClass at all, only defineClass, which is a final method and cannot be overridden (and after a check is a native method). So it absolutely does not matter what any classloader subclass does.

You are right about the leak though, sorry. We should weak reference the ArrayLists as well in our holders map, or we still hold strong refs to the classloader.

Honestly, both solutions are quite similar, just mine is half the lines of code, because it does not customize the class, and does not implement some kind of classloaderlocals map. But maybe that last one is useful?

---

But I must restate that this is not a good solution at all. Because this problem is not related to classloading, just classloading makes it worse since it fills up permgen.

Imagine a heavyweight view in a GUI app that registers observers, but fails deregister them; after opening that view lots of time, the vm has a lot of objects that are still reachable through observable-&gt;listener-&gt;target, worse, they still get signals and process them. But these objects will never do anything visible, they belong to long ago removed views.

Only a WeakObservable is a real solution. Slightly more difficult as the regular Observable, since you must ensure to strongly hold on to the listeners you give it.

However, you will quickly see a bug appear around views not receiving signals even after you have register them ... and bugs programmers can fix. Memory leaks are much harder to find and fix.


good discussion indeed :)

-Onne</description>
		<content:encoded><![CDATA[<p>@Jevgeni Kabanov</p>
<p>1. It does not violate the spec, since the last two of the four condition for link failure are not met.</p>
<p>2. My solution does not depend on loadClass at all, only defineClass, which is a final method and cannot be overridden (and after a check is a native method). So it absolutely does not matter what any classloader subclass does.</p>
<p>You are right about the leak though, sorry. We should weak reference the ArrayLists as well in our holders map, or we still hold strong refs to the classloader.</p>
<p>Honestly, both solutions are quite similar, just mine is half the lines of code, because it does not customize the class, and does not implement some kind of classloaderlocals map. But maybe that last one is useful?</p>
<p>&#8212;</p>
<p>But I must restate that this is not a good solution at all. Because this problem is not related to classloading, just classloading makes it worse since it fills up permgen.</p>
<p>Imagine a heavyweight view in a GUI app that registers observers, but fails deregister them; after opening that view lots of time, the vm has a lot of objects that are still reachable through observable-&gt;listener-&gt;target, worse, they still get signals and process them. But these objects will never do anything visible, they belong to long ago removed views.</p>
<p>Only a WeakObservable is a real solution. Slightly more difficult as the regular Observable, since you must ensure to strongly hold on to the listeners you give it.</p>
<p>However, you will quickly see a bug appear around views not receiving signals even after you have register them &#8230; and bugs programmers can fix. Memory leaks are much harder to find and fix.</p>
<p>good discussion indeed :)</p>
<p>-Onne</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jevgeni Kabanov</title>
		<link>http://dow.ngra.de/2009/06/15/classloaderlocal-how-to-avoid-classloader-leaks-on-application-redeploy/comment-page-1/#comment-14045</link>
		<dc:creator>Jevgeni Kabanov</dc:creator>
		<pubDate>Tue, 16 Jun 2009 11:51:06 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=926#comment-14045</guid>
		<description>@Onnne

Spec says it&#039;s not allowed  http://java.sun.com/docs/books/jvms/second_edition/html/ConstantPool.doc.html#78621 and loadClass() is overridden by almost any custom class loader in a variety of ways. Good luck with that, I had enough fun debugging such errors for a lifetime...

Also the &quot;working&quot; code you proposed leaks class loaders, since holders has strong references to listeners that hold the classes that hold the class loaders.

Read/Write lock might be a good idea, though. Thanks for the discussion!</description>
		<content:encoded><![CDATA[<p>@Onnne</p>
<p>Spec says it&#8217;s not allowed  <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ConstantPool.doc.html#78621" rel="nofollow">http://java.sun.com/docs/books/jvms/second_edition/html/ConstantPool.doc.html#78621</a> and loadClass() is overridden by almost any custom class loader in a variety of ways. Good luck with that, I had enough fun debugging such errors for a lifetime&#8230;</p>
<p>Also the &#8220;working&#8221; code you proposed leaks class loaders, since holders has strong references to listeners that hold the classes that hold the class loaders.</p>
<p>Read/Write lock might be a good idea, though. Thanks for the discussion!</p>
]]></content:encoded>
	</item>
</channel>
</rss>
