I run client code inside my application, much like a WebServer deploys/undeploys WebApps.
So I created a custom ClassLoader
that gets discarded to get rid of the client code. However, this doesn't work properly. When executing and analyzing with Elipse Memory Analyzer, I can see that the objects and the classloader are never garbage collected:
Somehow the problem seems to be related to the ThreadPoolExecutor
, which implements a finalize()
method. It was mentioned elsewhere, that finalizer methods are evil and can cause OutOfMemoryErrors
, because Finalizer thread runs with lower priority. However, when analyzing the application and thread stack with VisualVM, the Finalizer thread is not busy but waiting for new work to arrive:
"Finalizer" daemon prio=5 tid=0x00007fdb1484f800 nid=0x2603 in Object.wait() [0x000000010aaf6000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000079aaadf10> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
- locked <0x000000079aaadf10> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177)
Locked ownable synchronizers:
- None
JavaDoc of ReferenceQueue.remove(ReferenceQueue.java:135)
:
Removes the next reference object in this queue, blocking until either
one becomes available or the given timeout period expires.
Any ideas what can cause this problem and what to do about it? Every input is highly appreciated!
Edit: We are using jdk1.7.0_09.jdk, so I guess it has nothing to do with this bug.
Edit: When I let the application run long enough (and execute and discard enough client code) I do get OutOfMemoryErrors, so the VM should garbage collect the classes. Also, using the -verbose:gc
flag, I see the following log output after the classes should be ready for finalization and just before taking the HeapDump:
[Full GC 57007K->52790K(149544K), 0.2997010 secs]
Which means, that a full GC just took place.