如何分析PermGen的内容?

25

我想获取PermGen的转储,以查看它为什么会填满。有没有一种分析方法?我已经知道了像log4j、tomcat Web应用程序重载等常见嫌疑对象,但我的应用程序中还有一些自定义代理生成代码,我只是想看一下里面的情况。

这可能有什么办法吗?

4个回答

26

太棒了!这正是我所需要的! - Daniel
请问如何解决在Windows上运行此程序时出现的“附加到进程ID XXXX,请稍候...连接调试服务器超时错误(请启动SwDbgSrv.exe)”问题? - MiamiBeach

18

你可以使用标志:

-XX:+TraceClassLoading -XX:+TraceClassUnloading

当类从永久代加载或卸载时,它们的身份标识会被打印出来。如果添加-XX:+PrintGCDetails,还可以跟踪永久代的大小。

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

PermGen内存溢出错误的另一个嫌疑对象是字符串interning。检查您的代码中使用字符串intern的地方。


2
这并没有回答实际问题...如何转储permgen堆。 - Stephen C
@Stephen:你说得没错,但我希望在这种情况下已经足够了 :) - Eyal Schneider
虽然它并没有完全解决我的问题,但我仍然接受了它,因为它对我最有帮助。我编写了一个脚本来解析我的日志输出并计算所有加载类的大小,发现每个新生代只有160MB实在是不够用。(当我读到我的评论时,我至少看到了两个WTF) - Daniel

4
如果您想获取所有加载的类列表,可以使用 jconsole。单击类选项卡,然后单击“详细输出”。这将打印每个加载到stdout的类。我发现这对于追踪JAXB代理类问题非常有用。
您可能需要使用-Dcom.sun.management.jmxremote命令行选项启动应用程序,以便jconsole附加到它。

抱歉,我的PermGen已经快满了。而且我不知道是什么导致的。 - Daniel
请打印出填充PermGen空间的类,因为它们被加载。您能否重新启动应用程序并打开此日志记录? - mtpettyp
实际上,这与从第一个注释中提供-XX:+ TraceClassLoading -XX:+ TraceClassUnloading没有任何区别,因此是无用的。 - Daniel

4

不,我已经知道这个了,但我真的需要一种方法来查看里面已经有什么。 - Daniel
1
尝试使用-permstat,但只得到了以下错误信息:Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process - Jesse Glick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接