我该如何查看PermGen中具体存储了哪些内容?

4
在我的应用程序中,我遇到了PermGen内存不足的错误,并希望查看是什么导致了这个问题。
我已经通过VisualVM连接到了我的应用程序。
我想要查看到底是什么在我的应用程序中占用了这么多的PermGen内存,但是我不能在VisualVM中单独获取“PermGen Heap”。我只能获取标准HeapDump。
是否有可能使用VisualVM或其他工具找出到底是什么在占用我的所有PermGen内存?
更新: 这个问题被标记为“重复”,但实际上我没有在提到的主题中看到我的问题的答案。问题是我不知道如何列出确切地占用了我的PermGen空间的内存。
目前,从该主题中我知道以下提示:
1. 运行jmap -permstat并查看intern Strings占用了多少PermGen。好主意,它起作用了:现在我知道String Pool在我的情况下不是一个问题。
2. 运行jmap -permstat并查看类加载器消耗的内存。它可以工作,但AppClassLoader中有数百个类,这对我帮助不大。
3. 运行PrintStringTable.java util以查看哪些字符串占用内存。我无法在我的Windows 7 PC上运行它,因为我得到了“连接到进程ID XXXX,请等待...连接调试服务器时超时(请启动SwDbgSrv.exe)”的错误。
无论如何,这不是我的情况。
4. 通过指定JVM属性跟踪运行时的类加载。它可以工作,但不能帮助我理解是什么占用了内存,有数千个类被加载。
因此,我在这里看不到我的问题的答案。我知道PermGen不仅被类本身所占用,还被它们的静态成员占用。我该如何跟踪哪些类的静态成员消耗了内存?
如果我错过了这个答案,请告诉我。

1
类和堆栈帧存储在 PermGen 中。您是否有过多的类或线程(每个线程都有自己的堆栈)? - Steve Kuo
这是一个解决方案:https://dev59.com/UXE85IYBdhLWcg3wUBoZ - znurgl
静态方法/变量也存储在PermGen中,以及任何string.intern()的使用(在JDK7之前),还有其他一些东西。 - spudone
spudone,你所说的“静态方法进入PermGen”是什么意思? - MiamiBeach
1个回答

2
VisualVM的堆转储应该足以研究您的PermGen问题-我不得不解决过太多PermGen内存泄漏问题,而VisualVM始终是我的起点。

如果您执行堆转储,它将包括有关permgen的信息-类、类加载器等。个人而言,我使用Eclipse Memory Analyser tool,只需将整个转储加载进去即可提供泄漏嫌疑报告、重复类报告等。通常,我只需转到重复类列表,右键单击并选择“查找GC根”,然后您通常可以缩小一些问题。

这可能会有所帮助(尽管没有详细阅读): http://java.jiderhamn.se/2011/12/11/classloader-leaks-i-how-to-find-classloader-leaks-with-eclipse-memory-analyser-mat/

这似乎是相同的问题/答案: How to analyze PermGen space?

顺带一提,你在类加载方面做了什么特别的工作吗?是显式地重新加载或使用类加载器加载吗?它只是纯Java吗?还是在容器中运行?

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