記憶體分析器 (MAT)
1. 記憶體分析器 (MAT)
1.1 MAT介紹
MAT是Memory Analyzer tool的縮寫,指分析工具,
1.2 MAT作用
Eclipse Memory Analyzer 是一種快速且功能豐富的Java 堆分析器,可幫助您發現記憶體泄漏并減少記憶體消耗,
使用記憶體分析器分析具有數億個物件的生產堆轉儲,快速計算物件的保留大小,查看誰在阻止垃圾收集器收集物件,運行報告以自動提取泄漏嫌疑人,
2. MAT的安裝
2.1 下載安裝包
下載地址:https://www.eclipse.org/mat/
選擇版本(備注:最新版本1.12.0需要JDK11及以上,如果本地JDK環境是Java8選擇1.10.0版本)
進來直接選擇DownLod會被國內的防火墻給攔截,需要選擇國內鏡像,點擊 Select Another Mirror選擇China開頭的鏡像即可下載.

2.2 配置記憶體
將加載下來的zip安裝包解壓后,找到 MemoryAnalyzer.ini 修改記憶體(默認配置的記憶體較小,一般dump檔案都比較大,不改大會導致記憶體溢位)
配置 -Xmx
3. MAT的使用
Mat的使用步驟
打開Mat后File>OpenHeapDump打開一個對應的dump檔案后,此時對應的打開后結果如圖所示:
默認情況下打開該dump檔案后,直接展示的就是一個Overview(概覽)的頁簽,其中可以看到上面標注為(1,2)的地方所對應的圖示與Overview頁簽中所對應的部分圖示是相似的;如果你不小心關掉了Overview的頁簽,那么直接單擊當前dump頁簽第一行導航欄的第一個 I字的圖示即可,同理,如果此時想要打開Histogram,那么在不打開Overview的情況下,直接點擊第一行導航欄的第二個圖示即可;
4. 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:
上述所有被標注加粗的部分,是記憶體溢位dump分析時較為常用的功能點也是下面主要講解的內容,- Component Report:組件報告,分析屬于公共根包或類加載器的物件;
4.1 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的類資訊;
4.2 Dominator Tree
以占用總記憶體的百分比的方式來列舉出所有的實體物件,可以用來發現大記憶體物件;
如上圖所示:可以看到ConcurrentHashMap@0x60191cfa8這個物件占據了98.92%的堆大小,所以基本就可以斷定,當前專案之所以會down機的主要原因是,ConcurrentHashMap溢位所導致的問題;
那么當我們需要查看,當前該ConcurrentHashMap@0x60191cfa8物件都參考了那些資料,以及當前該物件是被那幾個物件所參考的,如何查看?
滑鼠在當前所要查看的物件右鍵,點擊List Objects可以看到分別提供了:with outgoing references(查看當前該物件的所有的參考資訊) 和 with incoming references(查看當前該物件是被那幾個物件所參考的) ;
4.3 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 (按類列出所有的累積物件)
Overview功能總結:
通過上述的解釋應該對當前Overview下的功能使用已經有了一個大概的了解,需要注意的是,Histogram 以及Dominator Tree時所主要提及的Shallow Size以及Retained Size以及在所列出的物件上右鍵查看參考關系,GCROOTS,以及左上角所展示的屬性明細等功能 是適用于所有的功能模塊的,
5. 一級導航欄功能說明
查看完上述關于Overview中的功能說明后,此處再來看一下Overview中不包含的一些功能:
5.1 Thread_Overview
如下圖所示,點擊一級導航欄的第5個圖示,可以用來查看當前行程dump時的所有執行緒的堆疊資訊,通過分析下面所對應的堆疊資訊,可以很快速的定位到對應的執行緒所執行的方法等層級關系,以此來定位對應的例外問題;
5.2 OQL
用于查詢Java堆的類SQL查詢語言
5.3 Heap Dump Overview
點擊一級導航欄的第6個圖示的下拉框下的 Heap Dump Overview,可以查看全域的記憶體占用資訊
5.4 Find Object by address
查看指定記憶體地址所對應的物件資訊:
6. 常見溢位的幾個場景
- 執行緒所參考物件溢位
- 靜態屬性物件溢位
執行緒堆疊所參考物件溢位的場景,如下圖:
本文來自博客園,作者:風光小磊,轉載請注明原文鏈接:https://www.cnblogs.com/lei-z/p/16440866.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/498409.html
標籤:Java
下一篇:java中重要關鍵字簡介說明
