Java Heap Dump 分析步驟 前言 配置 Heap Dump文件生成 Heap Dump分析

前言

生產環境中Java應用難免遇到Out Of Memory或內存持續佔用過大的問題。對於此類問題通用的分析方法是對問題進程的heap dump進行分析,重點關注佔用內存較大的對象。本篇爲大家帶來分析Java進程heap dump的方法。

事先需要準備軟下軟件包:

  • JDK 11+(目前MAT最新版本1.13.0要求使用)
  • Memory Analyzer Tool (MAT)

MAT官方下載頁面:Eclipse Memory Analyzer Open Source Project | The Eclipse Foundation

軟件包準備就緒後,解壓JDK和MAT到任意目錄,無需其他安裝操作。

配置

由於目前新版本的MAT工具需要JDK11或者更高版本的運行環境,如果機器環境爲JDK11以下,需要單獨爲MAT工具配置專門的JDK。方法爲編輯MAT安裝目錄中的MemoryAnalyzer.ini文件,在文件開頭加入如下內容:

-vm
/path/to/jdk-11.0.17+8/bin/java

/path/to/jdk-11.0.17+8/bin/java替換爲真實環境中JDK11的java可執行文件的路徑。

Heap Dump文件生成

這一節介紹下如何獲取Java進程的heap dump。

使用命令

使用命令可以立刻獲取某個Java進程的heap dump。

使用jmap命令:

jmap -dump:live,format=b,file=/path/to/heapdump.hprof <pid>

使用jcmd命令:

jcmd <pid> GC.heap_dump /path/to/heapdump.hprof

其中<pid>爲需要分析的Java進程的pid。/path/to/heapdump.hprof爲生成的heap dump文件所在的路徑。

在特定時間點生成

考慮到如下場景:我們需要獲取Java程序出現異常的時候(例如OOM)的heap dump。這種場景下我們無法使用上面講解的命令,Java進程出現問題的時候可能已經被系統kill掉。因此我們需要配置JVM,讓他能夠在特定時間點自動生成heap dump。

下面列出生成heap dump的時間點和對應的JVM參數。

在OOM的時候生成heap dump:

-XX:+HeapDumpOnOutOfMemoryError

在full GC前生成heap dump:

-XX:+HeapDumpBeforeFullGC

在full GC後生成heap dump:

-XX:+HeapDumpAfterFullGC

在按下ctrl+break的時候生成heap dump:

-XX:+HeapDumpOnCtrlBreak

注意:指定heap dump文件生成的路徑需要配置-XX:HeapDumpPath=/path/to/heapdump.hprof

使用VisualVM生成heap dump

生產環境多用命令或者JVM參數的方式生成heap dump。當然在本機開發測試的時候還可以使用圖形化工具生成heap dump,例如VisualVM等。

VisualVM的下載頁面:VisualVM: Download。下載後解壓到任意目錄,運行bin目錄下的visualvm可執行文件,打開它的圖形界面。

生成heap dump只需要在左邊的application選擇需要heap dump的進程,然後在右邊欄目依次點擊Monitor -> Heap Dump。如下圖:

注意:如果運行VisualVM的時候提示JDK找不到,需要爲VisualVM單獨配置。方法爲編輯VisualVM安裝目錄中的etc/visualvm.conf。修改或添加這一行:

visualvm_jdkhome="/path/to/java_home"

然後重新運行VisualVM。

Heap Dump分析

對於不是很大的heap dump文件(不大於MAT分析機器內存的1.2倍),我們可以將heap dump文件壓縮後下載到本地,使用MAT圖形界面方式分析。操作方法比較直觀(File -> Open Heap Dump...),這裏不再贅述。

生產環境中可能遇到特別大的heap dump。比如我們要分析一個30G的heap dump。將其在服務器上壓縮之後,空間佔用仍有大約10G,下載到本地耗時很長。本地開發機器一般也很少見32G內存機器,分析的時候會出現內存溢出問題。這種情況下我們需要使用MAT提供的命令行功能,在服務器上進行分析並輸出分析報告。這些分析報告是靜態的web頁面,只有幾百KB大小。需要在本地做的僅僅是將這些報告下載下來用瀏覽器打開,這樣完美避免了本地開發環境配置不足的問題。

在服務器上使用MAT命令行分析的方法很簡單。在MAT安裝目錄中執行:

./ParseHeapDump.sh xxx.hprof org.eclipse.mat.api:suspects org.eclipse.mat.api:overview org.eclipse.mat.api:top_components

其中xxx.hprof在實際使用的時候需要替換爲hprof文件的路徑。運行完畢後在hprof文件所在目錄會生成一系列的index/threads文件和3個壓縮文件。這3個壓縮文件是我們重點關注的分析報告,分別爲:

  • xxx_Leak_Suspects.zip:報告包含懷疑造成內存泄漏的地方,報告中包含了class層級圖。對於OOM的場景能夠很容易的定位到是哪個對象佔用了大量內存不釋放。
  • xxx_System_Overview.zip:包含heap dump基本信息,dump進程JVM的相關配置和線程信息等。
  • xxx_Top_Components.zip:查看佔用空間最大的幾個object/class/classloader/package等。報告以餅圖和表格的形式展示。通過這個報告可以定位出Java程序運行時哪些對象佔用內存較多,對問題排查和程序優化很有幫助。

這三個報告是分析問題的關鍵。我們通過報告找出內存佔用過大的對象,然後結合日誌和項目源代碼分析程序邏輯,逐步定位出問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章