3

在 java 堆转储中,我如何确切知道代码中的哪个位置/哪个线程导致了转储?

4

3 回答 3

4

读取内存转储:

我建议您从这里尝试“eclipse 内存分析器”

另一个选项(免费)是使用 JVisualVM(可在 $JAVA_HOME/bin 获得)打开它,jhat 也很酷,但已经被推荐 :)

现在,您要询问的是导致内存堆转储的线程,而不是如何进行内存转储......这取决于您如何获得内存转储。有不同的方法来获取转储。

  1. 在您的进程中,一旦遇到 OutOfMemory 错误,您可以指示 JVM 生成内存转储,在这种情况下,我相信它将是 JVM 本身。

  2. 假设您有一个 JMX 服务器与您的 JVM 示例一起运行,您可以从 MBean 触发堆转储创建

  3. 您甚至可以在应用程序外部使用系统调用(在 linux 上):kill -3 _YOUR_JAVA_PROCESS_ID_将生成 heapdump。

但我很难想象你为什么需要这样的信息。稍后在评论中您提到“确切的代码行”,但这些方式通常在您的 JVM 之外......您确定需要一行代码来生成堆转储本身,还是您正在尝试找出真正的问题?

希望这可以帮助

于 2012-08-03T07:05:44.643 回答
2

在 java 中,您在某个地方创建对象,在许多地方使用它,然后让 GC 将其收集回来。没有一条线会导致泄漏。

您应该在 MAP 等工具中寻找对象数量和它们使用的堆。选择每个目标类,看看为什么它们没有被垃圾收集。(有些人持有的参考超出了需要——比如说一个静态字段)

您可能会发现此页面上的说明更有用 - http://scn.sap.com/people/krum.tsvetkov/blog/2007/07/02/finding-memory-leaks-with-sap-memory-analyzer (也链接来自 MAT 主页)

于 2012-08-03T07:20:00.560 回答
1

尝试使用Java 堆分析工具 (jhat)或 jconsole(位于您的 JAVA_HOME\bin 中)。

于 2012-08-03T07:02:55.713 回答