1. 程式人生 > >獲取JVM轉儲檔案的Java工具類

獲取JVM轉儲檔案的Java工具類

在上期文章如何獲取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);
                    }
                }
            }
        }
    }


}
  • 重要說明:雖然可以從應用程式中轉儲多個堆快照,但不能將多個轉儲中的物件相關聯。jmap工具使用物件地址作為物件識別符號-在垃圾回收之間有所不同[回想一下GC可能會移動更改物件地址的物件]。但是,您可以通過彙總統計資料(例如直方圖等)進行關聯。

下面將生產好的heap.bin檔案拉回到本地或者在服務端用jhat -port 8888 heap.bin工具進行處理,然後訪問:http://localhost:8888即可檢視當時JVM堆記憶體的使用情況。
如圖:


  • 鄭重宣告:文章禁止第三方(騰訊雲除外)轉載、發表,事情原委測試窩,首頁抄我七篇原創還拉黑,你們的良心不會痛嗎?