生產環境中,一旦出現內存泄漏,長期運行下非常容易引發內存溢出(OutOfMemory,OOM)故障。爲此,JDK 提供了一些內存泄漏的分析工具,如 jconsole,jvisualvm 等,用於輔助開發人員定位問題,但是這些工具很多時候並不足以滿足快速定位的需求。
1.Heap Dump的生成
Linux 下使用 jmap 命令生成 Heap Dump:
# java -version // 檢驗java環境
# jps // 顯示當前所有 JVM 進程 pid 的命令
# jmap -dump:live,format=b,file=/dump/heap-dump.hprof <pid> // 比較耗時, 耐心等待
其中的 pid 是 JVM 的進程 id,/dump/heap-dump.hprof 是生成 dump 文件的目錄和名稱。
2.MAT的使用
MAT 工具是 Eclipse 的一個插件,可以單獨使用,使用起來非常方便,尤其是在分析大內存的 dump 文件時,可以非常直觀的看到各個對象在堆空間中所佔用的內存大小、類實例數量、對象引用關係、利用 OQL 對象查詢,以及可以很方便的找出對象 GC Roots 的相關信息,當然最吸引人的還是能夠快速爲開發人員生成內存泄露報表,方便定位問題和分析問題。
下載安裝 MAT https://www.eclipse.org/mat/downloads.php。
當成功啓動 MAT 後,通過菜單選項 “File -> Open Heap Dump…” 打開指定的 dump 文件後,將會生成 Overview 選項,如下所示:
頂部功能區說明:
功能說明 | |
---|---|
Overview | 顯示概要信息,並展示了一些常用功能的入口。 |
OQL | MAT 提供了一個對象查詢語言(OQL),類似於 SQL,將類當作表,對象當作記錄行,成員變量當作表中的字段。 |
Thread Overview | 此工具可以查看生成Heap Dump文件的時候線程的運行情況,用於線程的分析。 |
Run Expert System Test | 可以查看分析完成的HTML形式的報告,也可以打開已經產生的分析報告文件。 |
Open Query Browser | 提供了在分析過程中用到的工具。 |
Find Object by address | 通過十六進制的地址查找對應的對象。 |
Overview 常用功能入口說明:
功能說明 | |
---|---|
Histogram | 直方圖,可以查看每個類的實例的數量和大小。 |
Dominator Tree | 支配樹,列出 Heap Dump 中處於活躍狀態中的最大的幾個對象,默認按 retained size 進行排序,因此很容易找到佔用內存最多的對象。 |
Top Consumers | 按類、類加載器和包分別進行查詢,並以餅圖的方式列出最大的幾個對象。 |
Duplicate Classes | 列出被加載多次的類,結果按類加載器進行分組,目標是加載同一個類多次被類加載器加載。使用該工具很容易找到部署應用的時候使用了同一個庫的多個版本。 |
Leak Suspects | Run Expert System Test報告的一種,該報告分析了 Heap Dump並嘗試找出內存泄漏點,最後在生成的報告中對檢測到的可疑點做了詳細的說明。 |
Top Components | 列出佔用總堆內存超過 1% 的對象。 |