dead class loaders not garbage collected from permgen
garbage-collection, java, jvm, permgen, xalan
Solution
You have a classloader leak. The typical pattern goes like this.
- You create new classloader
- You load classes in new classloader
- You create an instance from one of the classes.
- You put instance into a data structure (for example) that makes it permanently reachable.
- You discard your reference to the classloader.
The problem is that so long as the instance that you created is reachable, we need 1) the code for the instance's classes methods 2) the `Class` object (or the infor to make it) in case someone calls `getClass()` on the instance.
That means that (in effect) the class must be reachable.
But the `Class` has a `getClassloader` method, so the classloader object must also be reachable.
And a typical classloader object has internal references to all of the classes that it loaded, so they must all be reachable too.
In short, make sure that you are not keeping references to instances of classes that you loaded using the dead classloader. They will prevent the classloader from being garbage collected.
Problem
I see the following from "jmap -permstat": ``` 0x000000077736cce0 12 173472 0x00000007723425d0 dead com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl$TransletClassLoader@0x00000007c83bea70 0x0000000777168a20 12 172264 0x00000007723425d0 dead com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl$TransletClassLoader@0x00000007c83bea70 0x0000000780b3c810 12 172264 0x00000007723425d0 dead com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl$TransletClassLoader@0x00000007c83bea70 0x0000000776ca6170 12 172264 0x00000007723425d0 dead com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl$TransletClassLoader@0x00000007c83bea70 0x00000007772b28a8 12 172264 0x00000007723425d0 dead com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl$TransletClassLoader@0x00000007c83bea70 .... ``` There are over 6000 of these dead TransletClassLoader class loaders in permGen now, and number keeps growing until I get this error: java.lang.OutOfMemoryError: PermGen space I have the following JVM flag set: -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSClassUnloadingEnabled ``` java version "1.6.0_33" Java(TM) SE Runtime Environment (build 1.6.0_33-b04) Java HotSpot(TM) 64-Bit Server VM (build 20.8-b03, mixed mode) ``` Why are these dead class loaders not getting cleaned up with the CMSClassUnloadingEnabled flag on? How do I fix this problem?