In my previous post we looked at different categories of ClassLoader leaks, and looked at a particular example of a refere nCE from outside the Web application ClassLoader (a JVM shutdown hooks pointing to a JAI class).
In this post we'll look at another category; Unterminated Threads running in your ClassLoader. This was a problem you can easily create yourself, but it could also come from third party libraries.
Understand: Before we introduced an instance of a class loader leak,-JVM's shutdown hook points to a Jai class. This section describes another reason for the class loader to leak: a thread that runs in the ClassLoader that does not terminate (contains an undead thread in a class loaded by the ClassLoader)
MAT analysis with running thread
When doing the ' load all ' classes from third party JARs ' Test mentioned in my former post, and analyzing it with the Techni Que outlined in my first post, I also ended up with this finding:
As can see, it's a thread still running inside my ClassLoader. We can also see, which the thread seems to is part of the Batik library. I was using version 1.5 beta 4, so let's dig into the sources.
org.apache.batik.util.SoftReferenceCache
(From line 181):
Private Static Thread cleanup; Static { new Thread () { publicvoid run () { while (true) {...}} ; Cleanup.setdaemon (true); Cleanup.start (); }
org.apache.batik.ext.awt.image.rendered.TileMap
(From line 139):
static Thread cleanup; static {cleanup = new Thread () { public
void
run () {
while (
true true ); Cleanup.start (); }
So. Not one but both static blocks (executing as the class is loaded) starting threads this execute in a while (true)
loop. Once Such a Threads is started, there are no garbage collecting their classloader–neither the ClassLoader having loaded T He Thread class (if a custom subclass to java.lang.Thread
), nor the Threads contextclassloader . In theory, the contextclassloader
of The thread can is changed (although I believe that rarely make s sense), but to garbage collect the ClassLoader of a custom Threads
subclass, the thread must stop Executing.
In newer versions of Batik, the both pieces of code above has been merged together into a new class– org.apache.batik.util.CleanerThread
. That ' s good. What's not good was that there was at the time of this writing still a while(true)
loop ... This problem have been reported, and a patch has been proposed.
Class loader leak Learning (iii) Kill thread--classloader leaks iii– "Die Thread, die!"