Java基礎 - JVM之Dump文件詳解
文章目錄
- Java基礎 - JVM之Dump文件詳解
- 一、什么是Dump
- 三、為什么需要Dump
- 分析思路
- 四、Dump記錄哪些內容
- 4.1 Java dump 文件的格式和內容
- 段格式
- 行格式
- 4.2 常用分類heap dump和thread dump
- heap dump
- thread dump
- 五、如何生產Dump文件
- 5.1 獲取heap dump文件
- 5.2 獲取heap dump文件
- 5.3 如果我們只需要將dump中存活的對象導出,那么可以使用:live參數
- 5.4 自動生成dump文件
- 六、Dump文件查看工具
- JDK命令
- jconsole 監控界面
- jvisualvm
- 阿里檢測命令工具Arthas
- Eclipse內存分析工具MAT(MemoryAnalyzerTool)
- Jprofiler
- 七、總結
學習Jvm調優,我們會接觸到Dump文件。什么是Dump文件、Dump文件是如何得到的。當程序崩潰時,如何從Dump文件還原崩潰時的信息。本文講重點講解。
一、什么是Dump
Thread Dump是非常有用的診斷Java應用問題的工具。每一個Java虛擬機都有及時生成所有線程在某一個點狀態的thread-dump的能力,雖然各個Java虛擬機打印的thread dump稍有不同,但是大部分提供了當前活動線程的快照及JVM中所有Java線程的堆棧跟蹤信息,堆棧信息一般包含完整的類名及所執行的方法,如果可能還有源碼的行數。
三、為什么需要Dump
服務器CPU,內存占用空間飆升,或者GC頻繁,首先需要排除的就是內存泄露,即內存中沒有的對象的空間沒有被及時回收導致的。而檢測內存泄露就需要看哪種類在內存占了較多份額,從而定位到代碼,然后修改。
分析思路
- CPU、MEM飆升,確定是否WEB服務的問題并記錄PID
- 查看GC情況,如果每次GC效果不明顯說明內存泄露
- 導出Dump并分析,定位占用top n的類
- 分析并找到 哪里創建的類占用了大量
四、Dump記錄哪些內容
4.1 Java dump 文件的格式和內容
Java dump通常的文本格式(.txt), 因此可用通過一般的文本編輯器進行閱讀,閱讀時需要注意段與行的格式:
-
段格式
為了方便分析,Java dump的每一段的開頭,都會有“----”與上一段明顯的區分開來,而每一段的標題也會用“====”作為標識,這樣我們能非常方便的找到開頭及其標題部分
清單1:JAVA dump標題示例
NULL --------------------------------
0SECTION TITLE subcomponent dump routine
NULL =============================== -
行格式
Java dump 文件中,每一行都包含一個標簽,這個標簽最多由 15 個字符組成(如清單2中所示)。其中第一位數字代表信息的詳細級別(0,1,2,3,4),級別越高代表信息越詳細;接下來的兩個字符是段標題的縮寫,比如,“CI” 代表 “Command-line interpreter”,“CL” 代表 “Class loader”,“LK” 代表 “Locking”,“ST” 代表 “Storage”,“TI” 代表 “Title”,“XE” 代表 “Execution engine”等等;其余部分為信息的概述。
1TISIGINFO Dump Event “uncaught” (00008000) Detail “java/lang/OutOfMemoryError” received
不同版本的 JVM 所產生的 Java dump 的格式可能會稍有不同,但基本上都會包含以下幾個方面的內容:
- TITLE 信息塊:描述 JAVA DUMP 產生的原因,時間以及文件的路徑
- GPINFO信息塊:GPF 信息。
- ENVINFO 信息塊:系統運行時的環境及 JVM 啟動參數。
- MEMINFO 信息塊:內存的使用情況和垃圾回收記錄。
- LOCKS 信息塊:用戶監視器(Monitor)和系統監視器(Monitor)。
- THREADS信息塊:所有 java 線程的狀態信息和執行堆棧。
- CLASSES信息塊:類加載信息。
4.2 常用分類heap dump和thread dump
-
heap dump
heap dump文件是一個二進制文件,它保存了某一時刻JVM堆中對象使用情況。HeapDump文件是指定時刻的Java堆棧的快照,是一種鏡像文件。Heap Analyzer工具通過分析HeapDump文件,哪些對象占用了太多的堆棧空間,來發現導致內存泄露或者可能引起內存泄露的對象。
-
thread dump
thread dump文件主要保存的是java應用中各線程在某一時刻的運行的位置,即執行到哪一個類的哪一個方法哪一個行上。thread dump是一個文本文件,打開后可以看到每一個線程的執行棧,以stacktrace的方式顯示。通過對thread dump的分析可以得到應用是否“卡”在某一點上,即在某一點運行的時間太長,如數據庫查詢,長期得不到響應,最終導致系統崩潰。單個的thread dump文件一般來說是沒有什么用處的,因為它只是記錄了某一個絕對時間點的情況。比較有用的是,線程在一個時間段內的執行情況。
兩個thread dump文件在分析時特別有效,困為它可以看出在先后兩個時間點上,線程執行的位置,如果發現先后兩組數據中同一線程都執行在同一位置,則說明此處可能有問題,因為程序運行是極快的,如果兩次均在某一點上,說明這一點的耗時是很大的。通過對這兩個文件進行分析,查出原因,進而解決問題。
五、如何生產Dump文件
使用的JDK工具在JDK_HOME/bin/目錄下,使用到jmap和jstack這兩個命令。
5.1 獲取heap dump文件
windows下切換到JDK_HOME/bin/,執行以下命令:jmap -dump:format=b,file=heap.hprof 2576
linux下切換到JDK_HOME/bin/,執行以下命令:./jmap -dump:format=b,file=heap.hprof 2576
這樣就會在當前目錄下生成heap.hprof文件,這就是heap dump文件。
5.2 獲取heap dump文件
windows下執行:jstack 2576 > thread.txt
inux下執行:./jstack 2576 > thread.txt
windows/linux則會將命令執行結果轉儲到thread.txt,這就是thread dump文件。有了dump文件后,我們就能借助性能分析工具獲取dump文件中的信息。
5.3 如果我們只需要將dump中存活的對象導出,那么可以使用:live參數
jmap -dump:live,format=b,file=heapLive.hprof 2576
5.4 自動生成dump文件
-
-XX:+HeapDumpOnOutOfMemoryError
當OutOfMemoryError發生時自動生成 Heap Dump 文件。這是一個非常有用的參數,因為當你需要分析Java內存使用情況時,往往是在OOM(OutOfMemoryError)發生時。
-
-XX:+HeapDumpBeforeFullGC
當 JVM 執行 FullGC 前執行 dump
-
-XX:+HeapDumpAfterFullGC
當 JVM 執行 FullGC 后執行 dump。
-
-XX:+HeapDumpOnCtrlBreak
交互式獲取dump。在控制臺按下快捷鍵Ctrl + Break時,JVM就會轉存一下堆快照。
-
-XX:HeapDumpPath=d:\dump.hprof
指定 dump 文件存儲路徑。注意:JVM 生成 Heap Dump 的時候,虛擬機是暫停一切服務的。如果是線上系統執行 Heap Dump 時需要注意。
六、Dump文件查看工具
定位排查問題時最為常?命令包括:jps(進程)、jmap(內存)、jstack(線程)、jinfo(參數)等。
- jps:查詢當前機器所有Java進程信息
- jmap:輸出某個 Java 進程內存情況
- jstack:打印某個 Java 線程的線程棧信息
- jinfo:用于查看jvm
JDK命令
-
jconsole 監控界面
-
jvisualvm
-
阿里檢測命令工具Arthas
-
Eclipse內存分析工具MAT(MemoryAnalyzerTool)
-
Jprofiler
七、總結
如果某種類型的對象太多,那么有可能是引用它的那個類的對象太多;基本上一些簡單頁面的查詢,結合原代碼,就可以初步定位內存泄漏的地方;綜上,dump文件結構還是比較簡單的,這對于分析線程的執行情況非常有用,也是每一個Java程序員必須掌握的高級技能之一;