我想得到 PermGen 的转储,看看它为什么会被填满。有没有办法分析这个?我已经知道 log4j、tomcat webapp 重新加载等常见嫌疑人,但我的应用程序中也有一些自定义代理生成代码,只是想看看幕后。
这有可能吗?
PermGen 通常由字符串文字池和加载的类组成。为了回答您的部分问题,即字符串文字池,我编写了一个实用程序来打印正在运行的 JVM 的字符串文字池。可在此处获得:
https://github.com/puneetlakhina/javautils/blob/master/src/com/blogspot/sahyog/PrintStringTable.java
它基于PermStat,这是 jmap 工具用于打印 permgen 统计信息的类。
您可以使用以下标志:
-XX:+TraceClassLoading -XX:+TraceClassUnloading
它们在从永久代加载/卸载时打印类的标识。如果添加-XX:+PrintGCDetails
,您还可以跟踪 permgen 的大小。
请注意,我不确定在 Sun 以外的 JVM 中是否支持这些标志。
PermGen out-of-memory-errors 的另一个嫌疑人是string interning。检查您在代码中实习字符串的位置。
jmap -permgen
符合要求吗?
请参阅 Java 的故障排除指南 http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/memleaks.html#gbyuu
如果您想获取所有已加载类的列表,您可以使用jconsole
. 单击类选项卡,然后单击“详细输出”。这将打印加载到的每个类stdout
。我发现这对跟踪 JAXB 代理类问题非常有用。
您可能必须使用-Dcom.sun.management.jmxremote
命令行选项启动您的应用程序jconsole
才能附加到它。