在上期文章 如何获取JVM堆转储文件 中,介绍了几种方法获取JVM的转储文件,其中编程方法是里面唯一一个从JVM内部获取的方法。这里就不演示了其他方法获取正在运行的应用程序的堆转储,重点放在了使用编程来获取转储文件的方法,并演示了如何使用jhat工具浏览/分析生成的二进制堆转储。
你可能想在各个时间点从应用程序中转储多个堆快照,然后使用jhat离线分析这些快照。如何以编程方式从应用程序中转储堆?下面给出了一个例子。您可以从应用程序中转储堆,但必须进行一些编程,如下所示:
package com.fun.utils; import com.fun.frame.SourceCode; import com.sun.management.HotSpotDiagnosticMXBean; import org.slf4j.Logger; import javax.management.MBeanServer; import java.lang.management.ManagementFactory; public class HeapDumper extends SourceCode { private static Logger logger = getLogger(); /** * 这是HotSpot Diagnostic MBean的名称 */ private static final String HOTSPOT_BEAN_NAME = "com.sun.management:type=HotSpotDiagnostic"; /** * 用于存储热点诊断MBean的字段 */ private static volatile HotSpotDiagnosticMXBean hotspotMBean; /** * 下载内存转储文件 * * @param fileName 文件名,例如:heap.bin,不兼容路径,会在当前目录下生成 * @param live */ static void dumpHeap(String fileName, boolean live) { initHotspotMBean(); try { hotspotMBean.dumpHeap(fileName, live); } catch (Exception e) { logger.error("生成内存转储文件失败!", e); } } /** * 初始化热点诊断MBean */ private static void initHotspotMBean() { if (hotspotMBean == null) { synchronized (HeapDumper.class) { if (hotspotMBean == null) { try { MBeanServer server = ManagementFactory.getPlatformMBeanServer(); hotspotMBean = ManagementFactory.newPlatformMXBeanProxy(server, HOTSPOT_BEAN_NAME, HotSpotDiagnosticMXBean.class); } catch (Exception e) { logger.error("初始化mbean失败!", e); } } } } } }
下面将生产好的 heap.bin
文件拉回到本地或者在服务端用 jhat -port 8888 heap.bin
工具进行处理,然后访问: http://localhost:8888
即可查看当时JVM堆内存的使用情况。
如图: