25

我想得到 PermGen 的转储,看看它为什么会被填满。有没有办法分析这个?我已经知道 log4j、tomcat webapp 重新加载等常见嫌疑人,但我的应用程序中也有一些自定义代理生成代码,只是想看看幕后。

这有可能吗?

4

4 回答 4

26

PermGen 通常由字符串文字池和加载的类组成。为了回答您的部分问题,即字符串文字池,我编写了一个实用程序来打印正在运行的 JVM 的字符串文字池。可在此处获得:

https://github.com/puneetlakhina/javautils/blob/master/src/com/blogspot/sahyog/PrintStringTable.java

它基于PermStat,这是 jmap 工具用于打印 permgen 统计信息的类。

于 2011-10-02T11:40:56.923 回答
18

您可以使用以下标志:

-XX:+TraceClassLoading -XX:+TraceClassUnloading

它们在从永久代加载/卸载时打印类的标识。如果添加-XX:+PrintGCDetails,您还可以跟踪 permgen 的大小。

请注意,我不确定在 Sun 以外的 JVM 中是否支持这些标志。

PermGen out-of-memory-errors 的另一个嫌疑人是string interning。检查您在代码中实习字符串的位置。

于 2010-05-16T08:18:53.867 回答
4

jmap -permgen符合要求吗?

请参阅 Java 的故障排除指南 http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/memleaks.html#gbyuu

于 2010-05-17T00:01:23.420 回答
4

如果您想获取所有已加载类的列表,您可以使用jconsole. 单击类选项卡,然后单击“详细输出”。这将打印加载到的每个类stdout。我发现这对跟踪 JAXB 代理类问题非常有用。

您可能必须使用-Dcom.sun.management.jmxremote命令行选项启动您的应用程序jconsole才能附加到它。

于 2010-05-16T17:47:54.627 回答