在上期文章如何獲取JVM堆轉儲文件中,介紹了幾種方法獲取JVM的轉儲文件,其中編程方法是裏面惟一一個從JVM內部獲取的方法。這裏就不演示了其餘方法獲取正在運行的應用程序的堆轉儲,重點放在了使用編程來獲取轉儲文件的方法,並演示瞭如何使用jhat工具瀏覽/分析生成的二進制堆轉儲。java
你可能想在各個時間點從應用程序中轉儲多個堆快照,而後使用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堆內存的使用狀況。
如圖:segmentfault