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