如何在Windows系统中最小化停机时间来获取堆转储?

4

我想找出为什么Elasticsearch节点上的JVM堆使用率一直保持在80%以上。为此,我通过运行命令来获取一个堆转储

jmap.exe -heap:format=b 5348

(5348是进程ID)。然后我可以使用VisualVM分析转储。

问题在于jmap在获取转储时会暂停JVM,因此节点基本上会下线约5分钟。

这篇文章提出了一种更快的方法,依赖于在Linux上使用gdb进行核心转储。我已经尝试过WinDbg,它创建了一个核心转储,但我无法在VisualVM中使用它。

Windows是否有类似的方法?如何在几秒钟内获取堆转储,而不是几分钟?


我会确保:a) 您正在使用二进制模式 b) 您的堆尽可能小,例如在进行转储之前最小化堆大小并触发一次完整的GC。 - Peter Lawrey
嗨,Peter。我使用二进制模式,请查看我的编辑后的问题,并为混淆感到抱歉。由于这是生产机器且运行大量数据,所以我无法拥有更小的堆。 - svetli-n
获取堆转储不会很便宜,因为它将不得不停止JVM以获得所有数据的一致快照。 - Peter Lawrey
@apangin - 现在可能很清楚,但当它被标记为垃圾邮件/冒犯性内容时并不是这样。 - ChrisF
1个回答

12

在您通过WinDbg获取核心转储后,您需要运行以下命令来提取堆转储:

jmap -heap:format=b "C:\Program Files\Java\...\bin\java.exe" core.mdmp

这可以脱机完成;不需要与正在运行的Java进程交互。然后,您将能够在VisualVM中打开生成的heap.bin


或者,您可以使用类直方图。它比完整堆转储产生得更快。

jmap -histo <PID>

它会显示占用堆空间最多的实例类的列表。这些信息通常足以让您了解内存泄漏发生的位置。


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