在 java 堆转储中,我如何确切知道代码中的哪个位置/哪个线程导致了转储?
3 回答
读取内存转储:
我建议您从这里尝试“eclipse 内存分析器”
另一个选项(免费)是使用 JVisualVM(可在 $JAVA_HOME/bin 获得)打开它,jhat 也很酷,但已经被推荐 :)
现在,您要询问的是导致内存堆转储的线程,而不是如何进行内存转储......这取决于您如何获得内存转储。有不同的方法来获取转储。
在您的进程中,一旦遇到 OutOfMemory 错误,您可以指示 JVM 生成内存转储,在这种情况下,我相信它将是 JVM 本身。
假设您有一个 JMX 服务器与您的 JVM 示例一起运行,您可以从 MBean 触发堆转储创建
您甚至可以在应用程序外部使用系统调用(在 linux 上):
kill -3 _YOUR_JAVA_PROCESS_ID_
将生成 heapdump。
但我很难想象你为什么需要这样的信息。稍后在评论中您提到“确切的代码行”,但这些方式通常在您的 JVM 之外......您确定需要一行代码来生成堆转储本身,还是您正在尝试找出真正的问题?
希望这可以帮助
在 java 中,您在某个地方创建对象,在许多地方使用它,然后让 GC 将其收集回来。没有一条线会导致泄漏。
您应该在 MAP 等工具中寻找对象数量和它们使用的堆。选择每个目标类,看看为什么它们没有被垃圾收集。(有些人持有的参考超出了需要——比如说一个静态字段)
您可能会发现此页面上的说明更有用 - http://scn.sap.com/people/krum.tsvetkov/blog/2007/07/02/finding-memory-leaks-with-sap-memory-analyzer (也链接来自 MAT 主页)
尝试使用Java 堆分析工具 (jhat)或 jconsole(位于您的 JAVA_HOME\bin 中)。