Mat使用詳解


背景

筆記中躺了很久的文章,今天用到Mat時發現之前寫的內容還算清晰,分享出來;
如下所舉例使用的dump文件是針對之前使用的ignite庫溢出時的dump文件;關於ignite的概念此處不再敘述,本篇文章重點則在於Mat即可

Mat的作用

MAT是Memory Analyzer tool的縮寫,是一種快速,功能豐富的Java堆分析工具,能幫助你查找內存泄漏和減少內存消耗。很多情況下,我們需要處理測試提供的hprof文件,分析內存相關問題,那么MAT也絕對是不二之選。 Eclipse可以下載插件結合使用,也可以作為一個獨立分析工具使用;下載地址:https://pan.baidu.com/s/1NDUR0E3WGrktm1qwoZHWfg
提取碼:agxr ;不用謝,雷鋒

Mat的使用步驟

打開Mat后File>OpenHeapDump打開一個對應的dump文件后,此時對應的打開后結果如圖所示:

默認情況下打開該dump文件后,直接展示的就是一個Overview(概覽)的頁簽,其中可以看到上面標注為(1,2)的地方所對應的圖標與Overview頁簽中所對應的部分圖標是相似的;如果你不小心關掉了Overview的頁簽,那么直接單擊當前dump頁簽第一行導航欄的第一個 I字的圖標即可,同理,如果此時想要打開Histogram,那么在不打開Overview的情況下,直接點擊第一行導航欄的第二個圖標即可;......

Overview下功能解釋

Overview頁簽下分別包含了:Actions,Reports,Step By Step 三大塊功能;每一塊功能下的子集所對應的作用分別是:

  • Actions:

    • Histogram 列出每個類所對應的對象個數,以及所占用的內存大小;

    • Dominator Tree 以占用總內存的百分比的方式來列舉出所有的實例對象,注意這個地方是直接列舉出的對應的對象而不是類,這個視圖是用來發現大內存對象的

    • Top Consumers:按照類和包分組的方式展示出占用內存最大的一個對象

    • Duplicate Classes:檢測由多個類加載器所加載的類信息(用來查找重復的類)

  • Reports:

    • Leak Suspects:通過MAT自動分析當前內存泄露的主要原因

    • Top Components:Top組件,列出大於總堆1%的組件的報告

  • Step By Step:

    • Component Report:組件報告,分析屬於公共根包或類加載器的對象;

    上述所有被標注加粗的部分,是內存溢出dump分析時較為常用的功能點也是下面主要講解的內容。

原創聲明:作者:Arnold.zhao 博客園地址:https://www.cnblogs.com/zh94

Histogram

通過Histogram 列出每個類所對應的對象個數,以及所占用的內存大小;

此處選中一個ClassName單擊后,通過左上角Inspector可以看到當前類的回收情況,內存地址,等

補充解釋:

  • 字段一:表示當前類所對應的對象數量

  • 字段二:Shallow Size是對象本身占據的內存的大小,不包含其引用的對象。對於常規對象(非數組)的Shallow Size由其成員變量的數量和類型來定,而數組的ShallowSize由數組類型和數組長度來決定,它為數組元素大小的總和;

  • 字段三:Retained Size=當前對象大小+當前對象可直接或間接引用到的對象的大小總和。(間接引用的含義:A->B->C,C就是間接引用) ,並且排除被GC Roots直接或者間接引用的對象;

關於紅框內的Statics,Attributes,Classhierarchy,Value則分別表示當前類的靜態變量,屬性,當前類的層次結構圖,以及當前類所對應的值Value;

注意:當前Histogram的列屬性:ClassName,Objects,ShallowHeap,RetainedHeap這幾個列屬性下面都是有提供一個輸入框,通過該輸入框可以進行相關類的檢索,比如:在ClassName下輸入一個正則.quark.那么則獲取到所有包路徑為quark的類信息;

Dominator Tree

以占用總內存的百分比的方式來列舉出所有的實例對象,可以用來發現大內存對象;

如上圖所示:可以看到ConcurrentHashMap@0x60191cfa8這個對象占據了98.92%的堆大小,所以基本就可以斷定,當前項目之所以會down機的主要原因是,ConcurrentHashMap溢出所導致的問題;

那么當我們需要查看,當前該ConcurrentHashMap@0x60191cfa8對象都引用了那些數據,以及當前該對象是被那幾個對象所引用的,如何查看?

鼠標在當前所要查看的對象右鍵,點擊List Objects可以看到分別提供了:with outgoing references(查看當前該對象的所有的引用信息) 和 with incoming references(查看當前該對象是被那幾個對象所引用的) ;

原創聲明:作者:Arnold.zhao 博客園地址:https://www.cnblogs.com/zh94

Leak Suspects

通過MAT自動分析當前內存泄露的主要原因

可以看到,當前MAT所給出內存泄露的主要原因是:當前實例java.util.concurrent.ConcurrentHashMap被加載自system class loader,共占用了 98.92%的堆內存,這個實例被引用自org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl並且這個CacheObjectBinaryProcessorImpl這個對象是加載自LaunchedURLClassLoader這個類加載器;

並且還給出了所對應的主要關鍵詞是:

java.util.concurrent.ConcurrentHashMap$Node[]
java.util.concurrent.ConcurrentHashMap
org.springframework.boot.loader.LaunchedURLClassLoader @ 0x6000a6860

基本上可以說是很詳細了,一語中的,如果想要查看明細,可以直接點擊detail,里面有更詳細的說明,如下圖所示:

上圖分別說明了到該內存泄漏的對象的最快路徑,也就是列出了當前ConcurrentHashMapConcurrentHashMap@0x60191cfa8這個對象所對應的被引用關系:可以看到當前引起內存泄漏的ConcurrentHashMap被CacheObjectBinaryProcessorImpl@0x60191cea8這個對象的metadataLocCache這個屬性所引用,而CacheObjectBinaryProcessorImpl這個對象又被GridKernalContextImpl @ 0x601821bf8這個對象的cacheObjeProc這個屬性所引用,以此遞推;

除此之外,還有以下三個被隱藏的信息,點擊即可查看明細:
Accumulated Objects in Dominator Tree (主控樹中的累積對象),Accumulated Objects by Class in Dominator Tree(主控樹中的按類累積對象 ,All Accumulated Objects by Class (按類列出所有的累積對象)

原創聲明:作者:Arnold.zhao 博客園地址:https://www.cnblogs.com/zh94

Overview功能說明結尾

通過上述的解釋應該對當前Overview下的功能使用已經有了一個大概的了解,需要注意的是,Histogram 以及Dominator Tree時所主要提及的Shallow Size以及Retained Size以及在所列出的對象上右鍵查看引用關系,GCROOTS,以及左上角所展示的屬性明細等功能 是適用於所有的功能模塊的,后續不再贅述;

一級導航欄功能說明

查看完上述關於Overview中的功能說明后,此處再來看一下Overview中不包含的一些功能

Thread_Overview

如下圖所示,點擊一級導航欄的第5個圖標,可以用來查看當前進程dump時的所有線程的堆棧信息,通過分析下面所對應的堆棧信息,可以很快速的定位到對應的線程所執行的方法等層級關系,以此來定位對應的異常問題;

OQL

用於查詢Java堆的類SQL查詢語言

Heap Dump Overview

點擊一級導航欄的第6個圖標的下拉框下的 Heap Dump Overview,可以查看全局的內存占用信息

Find Object by address

查看指定內存地址所對應的對象信息;

常見溢出的幾個場景

1、線程所引用對象溢出
2、靜態屬性對象溢出

線程棧所引用對象溢出的場景,如下:

Mat各功能內還有很多小的子功能,使用過程中可逐步嘗試,此處不再贅述

原創聲明:作者:Arnold.zhao 博客園地址:https://www.cnblogs.com/zh94


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM