堆转储是诊断与内存相关的问题(例如内存泄漏缓慢,垃圾回收问题和 java.lang.OutOfMemoryError。它们也是优化内存消耗的重要工具。

有很多很不错的的工具,例如 Eclipse MAT 和 Heap Hero,可以分析堆转储。但是,您需要为这些工具提供以正确的格式和正确的时间点捕获的堆转储。

本文为您提供了捕获堆转储的多个选项。但是,我认为前三个是有效的选择,而其他三个则是个不错的选择。

jmap

jmap 打印堆转储到指定的文件位置。该工具打包在 JDK 中。可以在JAVA_HOMTE\bin文件夹中找到它。

这是调用 jmap 的方法:

jmap -dump:format=b,file=<file-path> <pid> 

where
pid: is the Java Process Id, whose heap dump should be captured
file-path: is the file path where heap dump will be written in to.

例:
jmap -dump:format=b,file=/opt/tmp/heapdump.bin 37320

HeapDumpOnOutOfMemoryError

当应用程序遇到 java.lang.OutOfMemoryError 时,理想的方法是立即捕获堆转储以诊断问题,因为您想知道 java.lang.OutOfMemoryError 发生时内存中有哪些对象以及它们占据的内存百分比。但是,由于很多方面的原因,大多数情况下,IT/运营团队都无法及时捕获堆转储。不仅如此,他们还重新启动了应用程序。如果没有在正确的时间捕获堆转储,就很难诊断出任何内存问题。

这就是该选项非常方便的地方。在应用程序启动期间传递 “ -XX:+ HeapDumpOnOutOfMemoryError” 系统属性时,JVM 将在 JVM 遇到 OutOfMemoryError 时立即捕获堆转储。

用法:

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/tmp/heapdump.bin

jcmd

jcmd 工具用于将诊断命令请求发送到 JVM。它打包为 JDK 的一部分。可以在JAVA_HOMTE\bin文件夹中找到它。

这是调用 jcmd 的方法:

jcmd <pid> GC.heap_dump <file-path>
where
pid: is the Java Process Id, whose heap dump should be captured
file-path: is the file path where heap dump will be written in to.

例:

jcmd 37320 GC.heap_dump /opt/tmp/heapdump.bin

JVisualVM

JVisualVM 是一个监视,故障排除工具,打包在 JDK 中。启动此工具时,您可以看到本地计算机上正在运行的所有 Java 进程。您也可以使用此工具连接到在远程计算机上运行的 Java 进程。

步骤:

从JVisualVM捕获堆转储

JMX

有一个 com.sun.management:type=HotSpotDiagnostic MBean。此 MBean 具有 “dumpHeap” 操作。调用此操作将捕获堆转储。'dumpHeap'操作采用两个输入参数:

您可以使用 JConsole,jmxsh,Java Mission Control 等 JMX 客户端来调用此 MBean 操作。我这里使用了 jconsole:

使用JConsole作为JMX客户端来生成堆转储

编程代码

除了使用工具之外,您还可以以编程方式从应用程序中捕获堆转储。在某些情况下,您可能希望基于应用程序中的某些事件来捕获堆转储。可以通过调用com.sun.management:type=HotSpotDiagnostic MBean JMX Bean,提供了从应用程序捕获堆转储的源代码。


↙↙↙阅读原文可查看相关链接,并与作者交流