Dump文件分析工具 - MAT圖文解析

/ 前言 /

在講解Mat工具之前我們先來看下幾個關於Dump/文件的問題

  • Dump文件是什麼

    Dump文件是進程的內存鏡像。可以把程序的執行狀態通過調試器保存到dump文件中

  • 我們拿到Dump文件有什麼用的?

    假如JVM因爲內存溢出的原因宕機了, 而程序的日誌裏面並沒有關於溢出所在對象的信息, 此時我們就需要通過分析Dump文件來找到問題原因

  • Dump文件怎麼生成?

    • 第一種

      在啓動JVM時指定參數

        # 指定生成Dump文件的異常類型
        -XX:+HeapDumpOnOutOfMemoryError
        # 指定Dump文件生成的位置
        -XX:HeapDumpPath=/usr/local/jvm/dumps
      
    • 第二種

      如果你在啓動JVM時沒有指定參數, 那麼可以使用第二種方式來生成Dump文件, 使用JVM自帶的工具jmap

      jmap -dump:file=/usr/local/jvm/dumps/check.dump PID
      

      PID的獲取可以通過ps | top指令來獲取

      ps -ef|grep java
      
      top
      

/ 1 / 安裝Mat

Mat是Eclipse的一個插件, 也可以獨立運行, 所以即使你使用IDEA也可以獨立使用Mat
Mat官網下載地址

根據操作系統選擇對應的版本即可
下載下來是一個zip壓縮包解壓即可
Mac解壓後是一個.app, 直接運行會報錯

我們需要修改一下啓動方式或者將.app文件移動到應用程序下

/Users/xxx/Downloads/mat.app/Contents/MacOS/MemoryAnalyzer -data ./workspace

啓動後的界面

啓動後在導入Dump文件時有可能會報錯

An internal error occurred during: "Parsing heap dump from 'xxx.dump'".
Java heap space

這是因爲Dump文件的大小超出了Mat默認的讀取範圍, 我們需要修改Mat的配置文件
找到MemoryAnalyzer.ini文件
Windows/Linux中該文件就在解壓縮的目錄下
Mac中該文件在mat.app/Contents/Eclipse

-startup
../Eclipse/plugins/org.eclipse.equinox.launcher_1.5.0.v20180512-1130.jar
--launcher.library
../Eclipse/plugins/org.eclipse.equinox.launcher.cocoa.macosx.x86_64_1.1.700.v20180518-1200
-vmargs
-Xmx4g
-Dorg.eclipse.swt.internal.carbon.smallFonts
-XstartOnFirstThread

修改-Xmx的值即可

/ 2 / Mat功能介紹

2 . 1 Overview

Dump文件信息, 使用餅狀圖的方式來展示內存佔用的信息

  • Details是文件信息詳情, 包含了文件大小、字節碼文件大小、對象文件大小、類加載器數量
  • Actions是常用的操作彙總, 與左上角的菜單功能相同

2 . 2 Histogram

Histogram彙總了使用到的類的對象數量以及堆佔用空間

我們還可以根據實際情況對Histogram展示的數據進行分類

在結果的第二行<Regex>中我們可以進行模糊查詢

2 . 3 Dominator_Tree

Dominator_Tree彙總了堆內存空間中佔比最大的對象, 按照空間大小排序, 我們可以通點擊左邊的箭頭符號查看當前對象的引用狀況, 最右側爲當前對象所佔空間比例

2 . 4 OQL

OQL是Object Query Language的簡寫,即對象查詢語言, 語法與SQL類似, 點擊上方的紅色感嘆號開始執行

2 . 5 Thread_Overview

線程視圖, 彙總了Dump文件中所有線程的信息, 按照線程所佔用的空間進行排序

2 . 6 Leak Suspects

內存泄漏疑點, 這是Mat根據Dump文件的分析結果得到最有可能導致OOM的疑點, 也是我在使用Mat工具時第一個打開的工具

點擊Details查看詳細分析信息

2 . 7 Path to GC Roots & Merge Shortest Paths to GC Roots

研究這倆個工具之前我們需要先了解一下GC對不同引用關係之間的區別

2 . 7 . 1 GC對不同引用關係之間的區別
  • 虛引用(PhantomReference)
    虛引用無法決定一個對象的生命週期, 因爲持有虛引用的對象和沒有引用一樣, 隨時都會被GC回收, 且虛引用的使用必須搭配引用隊列一起使用PhantomReference
  • 弱引用(WeakReference)
    與虛引用相比擁有短暫的生命週期, 長短則取決於GC什麼時候回發現它, 需要搭配WeakReference來使用
  • 軟引用(SoftReference)
    與弱引用相比, 軟引用的生命週期長短取決於堆內存是否充足, 如果堆內存已經滿了, 那麼GC就會回收軟引用對象
  • 強引用(StrongReference)
    我們平常創建對象時都是創建的強引用對象, 不論堆內存是否充足, 只要該對象還存在引用關係GC就不會回收, 這也是OOM異常的觸發原因
2 . 7 . 2 Path to GC Roots

當前對象到GC Root的路徑, 也就是當前對象的引用關係, 該工具只能展示單個對象的引用關係, 所以只能在Dominator_Tree中使用

2 . 7 . 3 Merge Shortest Paths to GC Roots

一組對象到GC Root的最短路徑, 效果與Path to GC Roots相同, 可以在Histogram中使用

選擇一條數據點擊右鍵並選擇Path To GC Roots, 選擇展示結果排除需引用、弱引用、軟引用, 我們只需要看強引用即可

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