Java堆分析器 - Eclipse Memory Analyzer Tool(MAT)

       Java堆(heanp dump)文件是一個純二進制文件,咱們用肉眼去看肯定是不現實的。所以咱們得藉助特定的堆分析器來對dump文件做相應的分析。這裏我們選用Eclipse Memory Analyzer(MAT)來作爲heap dump文件的分析工具。接下來咱們對MAT工具做一個簡單的介紹。方便咱們後續分析Java堆(heap dump)

       Eclipse Memory Analyzer Tool(簡稱MAT)是一個非常強大的的內存分析工具,可以幫助我們分析堆內存,找到內存泄露的地方,減少內存消耗。MAT除了可以作爲Eclipse的插件使用。官方也提供了獨立的安裝版本,我們用IDEA用的比較多,所以使用獨立的安裝版本,直接進入下載頁面 https://www.eclipse.org/mat/downloads.php ,下載適合自己的版本。爲了方便大家我這裏提前下載了一份Window 64位的安裝包 https://download.csdn.net/download/wuyuxing24/12302636

       在介紹MAT工具之前我們先介紹幾個常用術語。在MAT工具中這幾個術語經常出現:

  • Shallow Size: 對象自身佔用的內存大小。
  • Retained Size: 對象本身的Shallow Size + 該對象直接或間接引用到的對象的Shallow Size。(也就是說Retained Size就是該對象被GC之後所能回收的內存的總和)
  • GC Roots: 是一組必須活躍的引用。GC會收集那些不是GC Roots且沒有被GC roots引用的對象。基本思路就是通過一系列名爲GC Roots 的對象作爲起始點開始向下搜索。如果一個對象到GC Roots沒有任何引用鏈相連時,則說明此對象不可用。換句話說就是能被遍歷到的(可到達的)對象就被判定爲存活,沒有被遍歷到的就自然被判定爲死亡。

哪些對象可以作爲Gc Roots的對象:

  • 虛擬機(棧幀中的本地變量表)中引用的對象
  • 方法區中類靜態屬性引用的對象
  • 方法區中常量引用的對象
  • 本地方法棧中JNI(即一般說的native方法)中引用的對象

在這裏插入圖片描述

一 MAT結構介紹

在這裏插入圖片描述

1.1 區域一:Inspector區域

       用於展示指定對象的詳細信息(選定一個對象的時候),從上到下依次是:內存地址、加載器名稱、包名、對象名稱、對象所屬類的父類、對象所屬類的加載器對象對象的堆內存大小(shallow size)、保留大小(retained size)、gc roots信息。

1.2 區域二:Inspector區域下方的區域

       展示對象的一些屬性信息、類層級信息。

1.3 區域三:常用工具欄區域

       常用工具按鈕從左到右依次是:概覽(Overview)、類直方圖(Histogram)、支配樹(Dominator Tree)、OQL查詢、線程視圖、報告相關、詳細功能(提供了一些更細緻的分析能力)。

1.4 區域四:功能視圖區域

       根據選擇的功能不同,該區域顯示對應功能的詳細信息。比如我們想看Overview信息(點擊區域三常用工具欄的第一個按鈕)該區域就會展示heap dump Overview對應的信息。

二 MAT視圖,功能

2.1 Overview視圖

在這裏插入圖片描述

進入Overview視圖

  • 使用MAT打開一個heap dump文件,解析完成後,默認就會進入Overview視圖頁面。
  • 工具欄中點擊Overview按鈕(區域三常用工具欄的第一個按鈕)展示Overview對應的信息。
    在這裏插入圖片描述
    Overview視圖使用

       Overview視圖界面包括兩個部分:一個是對heap dump文件的一個大致的分析,包括佔用內存大小,類個數,對象個數,類加載器個數,及用餅圖的方式展示對象retained size信息、另一個是提供了一些常用的入口,包括視圖入口(Actions)、常用的分析報告入口(Reports)、MAT使用教程入口(Step By Step)]。

       關於Overview視圖區域,我們得關注點應該放在餅圖上(根據retained size 對所有對象做排序,使用拼圖演示結果)。我們可以方便的看到哪些對象的ratained size比較大(如果某個對象的retained size特別大。我們就要特別小心了,可能有問題了)。當我們鼠標點擊每個餅圖區域(對象)的時候,會彈出一個菜單,我們還可以查看相應對象的詳細信息。這個菜單包含的額內容有:

在這裏插入圖片描述

  • List objects:
  • with ontgoing references:查看當前對象持有的外部對象引用。
  • with incoming references:查看當前對象被那些外部對象所引用。
  • Show objects by class
  • with ontgoing references: 查看這個對象類型持有的外部對象引用
  • with ontgoing references: 查看這個對象類型被哪些外部對象引用
  • Path To GC Roots: 從對象到GC Roots的路徑。這個路徑解釋了爲什麼當前對象還能存活,對分析內存泄露很有幫助。(這個查詢只能針對單個對象使用)。這裏面可能需要咱們對引用有一定的瞭解,咱們也做一個簡單的介紹。

       強引用(strong reference): 大家平常寫代碼的引用都是這種類型的引用,它可以防止引用的對象被垃圾回收。軟引用(soft reference): 內存溢出之前進行回收,GC時內存不足時回收,如果內存足夠就不回收。弱引用(weak reference): 每次GC時回收,無論內存是否足夠。虛引用(phantom reference):每次垃圾回收時都會被回收,主要用於監測對象是否已經從內存中刪除。

  • with all references: 從GC Roots節點到該對象的引用路徑,包含所有引用類型。
  • exclude weak references:從該對象到GC Roots節點的最短引用路徑,去除弱引用。
  • exclude soft references:從該對象到GC Roots節點的最短引用路徑,去除軟引用。
  • exclude pahantorn references:從該對象到GC Roots節點的最短引用路徑,去除虛引用。
  • exclude weak/soft references:從該對象到GC Roots節點的最短引用路徑,去除弱引用,軟引用。
  • exclude phantom/soft references:從該對象到GC Roots節點的最短引用路徑,去除虛引用,軟引用。
  • exclude phantom/weak references:從該對象到GC Roots節點的最短引用路徑,去除虛引用,弱引用。
  • exclude all phantom/weak/soft etc. references:從該對象到GC Roots節點的最短引用路徑,去除虛引用,弱引用,軟引用。
  • exclude custom references:從該對象到GC Roots節點的最短引用路徑,去除自定義引用。
  • Merge Shortest Paths to GC Roots: 從GC Roots到對象的共同路徑。

  • Java Basics:

  • References: 顯示引用和對象的統計信息,列出類加載器,包括定義的類
  • Class Loader Explorer: 列出選定對象的類裝載器,包括其定義的類 。
  • Customized Retained Set: 計算選中對象的保留堆,排除指定的引用。
  • Group By Value: 按對象的字符串表示形式對其進行分組。
  • Open In Domainator Tree: 對選中對象生成支配樹。
  • Show As Histogram: 展示任意對象的直方圖。
  • leak Identification:內存泄露識別。
  • Export Snapshot: 導出快照信息。
  • Immediate Dominators: 查看某個對象的dominator
  • Show Retained Set: 計算一個對象的保留堆大小
  • Copy: 拷貝一些屬性。
  • Search Queries: 搜索查詢相關。

2.2 Histogram視圖

在這裏插入圖片描述

進入Histogram視圖

  • 工具欄中點擊Histogram按鈕(區域三常用工具欄的第二個按鈕)。
    在這裏插入圖片描述
  • Overview頁面的Actions部分有進入Histogram視圖的快捷方式。
    在這裏插入圖片描述
    Histogram視圖使用

       Histogram視圖從Class類的維度展示每個Class類的實例存在的個數、 佔用的Shallow內存和Retained內存大小。

       咱們從Histogram視圖可以看出,哪個Class類的對象實例數量比較多,以及佔用的內存比較大,不過,多數情況下,在Histogram視圖看到實例對象數量比較多的類都是一些基礎類型,如char[](因爲其構成了String)、String、byte[],所以僅從這些是無法判斷出具體導致內存泄露的類或者方法的,可以使用 List objects 或 Merge Shortest Paths to GC roots 等功能繼續鑽取數據。如果Histogram視圖展示的數量多的實例對象不是基礎類型,是有嫌疑的某個類,如項目代碼中的bean類型,那麼就要重點關注了。

       如果存在內存溢出,時間久了溢出類的實例數量或者內存佔比會越來越多,排名也越來越靠前的。可以點擊工具類上的對比圖標進行對比,通過多次對比不同時間點下的直方圖對比就很容易把溢出的類找出來。

       每個類的詳細信息(鼠標右鍵某個類的時候彈出框)

  • List objects:
  • with ontgoing references:查看當前類的所有對象,並且列出這些對象持有的外部對象引用。
  • with incoming references:查看當前類的所有對象,並且列出這些對象被那些外部對象所引用。
  • Show objects by class
  • with ontgoing references: 查看這個對象類型持有的外部對象引用
  • with ontgoing references: 查看這個對象類型被哪些外部對象引用
  • Merge Shortest Paths to GC Roots: 從GC Roots到對象的共同路徑。

  • Java Basics:

  • References: 顯示引用和對象的統計信息,列出類加載器,包括定義的類
  • Class Loader Explorer: 列出選定對象的類裝載器,包括其定義的類 。
  • Customized Retained Set: 計算選中對象的保留堆,排除指定的引用。
  • Group By Value: 按對象的字符串表示形式對其進行分組。
  • Open In Domainator Tree: 對選中對象生成支配樹。
  • Show As Histogram: 展示任意對象的直方圖。
  • Java Collections
  • Array Fill Ratio: 輸出數組中,非基本類型、非null對象個數佔數組總長度的比例。
  • Arrays Grouped By Size: 顯示數組的直方圖,按大小分組。
  • leak Identification:內存泄露識別。
  • Export Snapshot: 導出快照信息。
  • Immediate Dominators: 查看某個對象的dominator
  • Show Retained Set: 計算一個對象的保留堆大小
  • Copy: 拷貝一些屬性。
  • Search Queries: 搜索查詢相關。
  • Calculate Minimum Retained Size(quick approx.): 計算最小的Ratined Size。
  • Calculate Precise Ratined Size: 精確計算Ratined Size。

2.3 Dominator Tree視圖

在這裏插入圖片描述
進入Dominator Tree視圖

  • 工具欄中點擊Dominator Tree按鈕(區域三常用工具欄的第三個按鈕)。
    在這裏插入圖片描述
  • Overview頁面的Actions部分有進入Dominator Tree視圖的快捷方式。
    在這裏插入圖片描述

Dominator Tree視圖使用

       Dominator Tree視圖中列出了每個對象(Object Instance)與其引用關係的樹狀結構,同時包含了佔用內存的大小和百分比。通過Dominator Tree視圖可以很容易的找出佔用內存最多的幾個對象(根據Retained Heap或Percentage排序)。Histogram視圖和Dominator Tree視圖都是可以用來幫助我們定位溢出源的。前者是基於類的角度,後者是基於對象實例的角度。Dominator Tree視圖可以更方便的看出其引用關係。

2.4 Top Consumers視圖

進入Top Consumers視圖

  • Overview頁面的Actions部分有進入Top Consumers視圖的快捷方式。
    在這裏插入圖片描述
    Top Consumers視圖使用

       Top Consumers視圖以圖形化的方式列出最大的object,可以按照object、class、classloader和package進行group by。說白了就是方便我們通過不同的方式站到佔內存最大的對象。

  • 按照對象查看內存佔用
    在這裏插入圖片描述
  • 按照類查看內存佔用
    在這裏插入圖片描述
  • 按照類加載查看內存佔用
    在這裏插入圖片描述
  • 按照包名查看內存佔用(根據包我們知道哪些公共用的到jar或自己的包占用。這樣就可以看到包和包中哪些類的佔用比較高)
    在這裏插入圖片描述

2.5 Duplicate Classes視圖

在這裏插入圖片描述

進入Duplicate Classes視圖

  • Overview頁面的Actions部分有進入Duplicate Classes視圖的快捷方式。
    在這裏插入圖片描述
    Duplicate Classes視圖使用

       Duplicate Classes視圖列出了被加載多次的類,結果按類加載器進行分組,目標是加載同一個類多次被類加載器加載。使用Duplicate Classes視圖很容易找到部署應用的時候使用了同一個庫的多個版本的問題。

三 MAT報告

3.1 Leak Suspects(內存泄露報告)

在這裏插入圖片描述
Leak Suspects進入

  • 使用MAT打開一個dump文件的時候,會彈出嚮導菜單,保持默認選項,點Finish,就會導向 Leak Suspects內存泄露報告頁面。
    在這裏插入圖片描述
  • 工具欄中點擊Run Expect System Test > Leak Suspects按鈕(區域三常用工具欄的第六個按鈕)。
    在這裏插入圖片描述
  • Overview頁面的Reports部分有進入Leak Suspects的快捷方式
    在這裏插入圖片描述

Leak Suspects使用

       Leak Suspects 列出了MAT幫我們分析的可能有內存泄露嫌疑的地方。MAT工具分析了heap dump文件之後非常直觀的展示了一個餅圖,餅圖深色區域被懷疑有內存泄漏的地方。而且下面會給出對懷疑內存泄露地方的具體描述信息。

       針對MAT幫我們分析出來的可能有內存泄露的地方。我們也可以進入查看懷疑地方的詳細信息(Leak Suspects如果有懷疑的地方)。
在這裏插入圖片描述

  • Description: 對懷疑內存泄露地方的一個描述信息。
    在這裏插入圖片描述
  • Shortest Paths To the Accumulation Point: 展示懷疑內存泄露對象的Path to GC Roots(就是持有可能泄漏內存對象的最近一層)。這個視圖的作用是可以分析是由於和哪個GC root相連導致當前Retained Heap佔用相當大的對象無法被回收。由於是分析內存泄露的報告,找到導致當前對象無法被回收的GC roots,分析這些GC roots是否合理,是有必要的。
    在這裏插入圖片描述
  • Accumulated Objects in Dominator Tree:以對象的維度展示了以懷疑對象爲根的Dominator Tree支配樹。 可以方便的看出受當前對象“支配”的對象中哪個佔用Retained Heap比較大。
    在這裏插入圖片描述
  • Accumulated Objects by Class in Dominator Tree:展示了以對象對象爲根的Dominator Tree支配樹,並以Class類分組。
    在這裏插入圖片描述
  • All Accumulated Objects by Class:列舉了懷疑對象所存儲的所有內容。
    在這裏插入圖片描述

3.2 Top Components

Top Components進入

  • 工具欄中點擊Run Expect System Test > Top Components按鈕(區域三常用工具欄的第六個按鈕)。
    在這裏插入圖片描述
  • Overview頁面的Reports部分有進入Top Components的快捷方式
    在這裏插入圖片描述

Top Components使用

       可以針對那些佔用堆內存超過整個堆內存1%大小的組件做一系列的分析。

在這裏插入圖片描述

       如上圖所示,列出報告中總內存佔用大於1%的組件。點擊每個組件。有可以查看每個組件的詳細信息。如下圖所示(點擊組件之後進入):

在這裏插入圖片描述

  • 餅圖:展示內存佔用大小。
  • Top Consumers:以圖形化的方式列出最大的object,上文中有講到Top Consumers哦
  • Retaines Set:是這個對象本身和他持有引用的對象和這些對象的retained set所佔內存大小的總和。
  • Possible Memory Waste:可能的內存垃圾。有一下幾個部分。
  • Duplicate Strings: 重複的字符串。
  • Empty Collections: 空集合。
  • Collection Fill Ratios: 集合使用率。
  • Miscellaneous:
  • Soft Reference Statistics: 軟引用統計。
  • Weak Reference Statistics: 弱引用統計。
  • Finalizer Statistics: Finalizer統計(設計Java Finalizer的使用)。
  • Map Collision Ratios: Map碰撞比例。

Leak Suspects用於查找內存泄漏問題,Top Components負責分析佔用堆內存超過整個堆內存1%大小的組件。

四 線程視圖

       線程視圖首先給出了在生成快照那個時刻,JVM中的Java線程對象列表。

進入線程視圖

  • 工具欄中點擊線程視圖按鈕。
    在這裏插入圖片描述

線程視圖的使用

       在線程視圖這個表中,可以看到以下幾個信息:線程對象的名字、線程名、線程對象佔用的堆內存大小、線程對象的保留堆內存大小、線程的上下文加載器、是否爲守護線程。

在這裏插入圖片描述

       選中某個線程對象展開,可以看到線程的調用棧和每個棧的局部變量,通過查看線程的調用棧和局部變量的內存大小,可以找到在哪個調用棧裏分配了大量的內存。

在這裏插入圖片描述

       上面我們僅僅是對MAT工具做了一個簡單的介紹,後續我們會根據一些實例,結合MAT的使用。做進一步的介紹。

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