我想获取PermGen的转储,以查看它为什么会填满。有没有一种分析方法?我已经知道了像log4j、tomcat Web应用程序重载等常见嫌疑对象,但我的应用程序中还有一些自定义代理生成代码,我只是想看一下里面的情况。
这可能有什么办法吗?
PermGen通常由字符串文字池和已加载的类组成。为了回答你问题中的一部分,即字符串文字池,我编写了一个实用程序来打印正在运行的JVM的字符串文字池。它可以在这里找到:
https://github.com/puneetlakhina/javautils/blob/master/src/com/blogspot/sahyog/PrintStringTable.java
它基于PermStat,这是jmap工具用来打印PermGen统计信息的类。
你可以使用标志:
-XX:+TraceClassLoading -XX:+TraceClassUnloading
当类从永久代加载或卸载时,它们的身份标识会被打印出来。如果添加-XX:+PrintGCDetails
,还可以跟踪永久代的大小。
请注意,我不确定这些标志是否在除Sun以外的JVM中受支持。
PermGen内存溢出错误的另一个嫌疑对象是字符串interning。检查您的代码中使用字符串intern的地方。
jconsole
。单击类选项卡,然后单击“详细输出”。这将打印每个加载到stdout
的类。我发现这对于追踪JAXB代理类问题非常有用。-Dcom.sun.management.jmxremote
命令行选项启动应用程序,以便jconsole
附加到它。jmap -permgen
能否满足需求?
关于Java的故障排除指南,请参阅 http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/memleaks.html#gbyuu
-permstat
,但只得到了以下错误信息:Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process
。 - Jesse Glick