堆转储是诊断与内存相关的问题(例如内存泄漏缓慢,垃圾回收问题和 java.lang.OutOfMemoryError。它们也是优化内存消耗的重要工具。
有很多很不错的的工具,例如Eclipse MAT和Heap Hero,可以分析堆转储。但是,您需要为这些工具提供以正确的格式和正确的时间点捕获的堆转储。
本文为您提供了捕获堆转储的多个选项。但是,我认为前三个是有效的选择,而其他三个则是个不错的选择。
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
当应用程序遇到java.lang.OutOfMemoryError时,理想的方法是立即捕获堆转储以诊断问题,因为您想知道java.lang.OutOfMemoryError发生时内存中有哪些对象以及它们占据的内存百分比。但是,由于很多方面的原因,大多数情况下,IT/运营团队都无法及时捕获堆转储。不仅如此,他们还重新启动了应用程序。如果没有在正确的时间捕获堆转储,就很难诊断出任何内存问题。
这就是该选项非常方便的地方。在应用程序启动期间传递“ -XX:+ HeapDumpOnOutOfMemoryError”系统属性时,JVM将在JVM遇到OutOfMemoryError时立即捕获堆转储。
用法:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/tmp/heapdump.bin
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是一个监视,故障排除工具,打包在JDK中。启动此工具时,您可以看到本地计算机上正在运行的所有Java进程。您也可以使用此工具连接到在远程计算机上运行的Java进程。
步骤:
JAVA_HOMTE/bin
有一个com.sun.management:type=HotSpotDiagnostic MBean。此MBean具有“dumpHeap”操作。调用此操作将捕获堆转储。'dumpHeap'操作采用两个输入参数:
您可以使用JConsole,jmxsh,Java Mission Control 等JMX客户端来调用此MBean操作。我这里使用了jconsole:
除了使用工具之外,您还可以以编程方式从应用程序中捕获堆转储。在某些情况下,您可能希望基于应用程序中的某些事件来捕获堆转储。可以通过调用 com.sun.management:type=HotSpotDiagnostic MBean JMX Bean
,提供了从应用程序捕获堆转储的源代码。