我在" 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
....
现在permGen中有超过6000个死的TransletClassLoader类加载器,并且数字一直在增长,直到我收到此错误:
java.lang.OutOfMemoryError:PermGen space
我设置了以下JVM标志:
-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)
为什么这些死类加载器没有被CMSClassUnloadingEnabled标志清除?我该如何解决这个问题?
答案 0 :(得分:4)
你有一个classloader泄漏。典型的模式是这样的。
问题在于,只要您创建的实例可以访问,我们就需要1)实例的类方法的代码2)Class
对象(或实现它的信息)以防有人在实例上调用getClass()
。
这意味着(实际上)必须可以访问该类。
但Class
有getClassloader
方法,因此类加载器对象也必须可以访问。
典型的类加载器对象具有对其加载的所有类的内部引用,因此它们也必须都可以访问。
简而言之,请确保您没有保留对使用死类加载器加载的类实例的引用。它们将阻止类加载器被垃圾收集。
答案 1 :(得分:1)
作为Stephens anser的后续内容,您可能需要查看this blog series of mine以了解如何跟踪类加载器泄漏。 或者您可能只想跳过并向您的应用程序添加my Classloader Leak Prevention library。
祝你好运!P.S。如果您进行调试并发现Xalan内部存在泄漏,请告知我们,以便我可以更新the list of known offenders。