筆記中躺了好久的文章,今天用到Mat時發現以前寫的內容還算清晰,分享出來;
以下所舉例使用的dump文件是針對以前使用的ignite庫溢出時的dump文件;關於ignite的概念此處再也不敘述,本篇文章重點則在於Mat便可java
MAT是Memory Analyzer tool的縮寫,是一種快速,功能豐富的Java堆分析工具,能幫助你查找內存泄漏和減小內存消耗。不少狀況下,咱們須要處理測試提供的hprof文件,分析內存相關問題,那麼MAT也絕對是不二之選。 Eclipse能夠下載插件結合使用,也能夠做爲一個獨立分析工具使用;下載地址:https://pan.baidu.com/s/1NDUR0E3WGrktm1qwoZHWfg
提取碼:agxr ;不用謝,雷鋒spring
打開Mat後File>OpenHeapDump打開一個對應的dump文件後,此時對應的打開後結果如圖所示:apache
默認狀況下打開該dump文件後,直接展現的就是一個Overview(概覽)的頁籤,其中能夠看到上面標註爲(1,2)的地方所對應的圖標與Overview頁籤中所對應的部分圖標是類似的;若是你不當心關掉了Overview的頁籤,那麼直接單擊當前dump頁籤第一行導航欄的第一個 I字的圖標便可,同理,若是此時想要打開Histogram,那麼在不打開Overview的狀況下,直接點擊第一行導航欄的第二個圖標便可;......數組
Overview頁簽下分別包含了:Actions,Reports,Step By Step 三大塊功能;每一塊功能下的子集所對應的做用分別是:dom
Actions:ssh
Histogram 列出每一個類所對應的對象個數,以及所佔用的內存大小;工具
Dominator Tree 以佔用總內存的百分比的方式來列舉出全部的實例對象,注意這個地方是直接列舉出的對應的對象而不是類,這個視圖是用來發現大內存對象的測試
Top Consumers:按照類和包分組的方式展現出佔用內存最大的一個對象插件
Duplicate Classes:檢測由多個類加載器所加載的類信息(用來查找重複的類)線程
Reports:
Leak Suspects:經過MAT自動分析當前內存泄露的主要緣由
Top Components:Top組件,列出大於總堆1%的組件的報告
Step By Step:
上述全部被標註加粗的部分,是內存溢出dump分析時較爲經常使用的功能點也是下面主要講解的內容。
原創聲明:做者:Arnold.zhao 博客園地址:https://www.cnblogs.com/zh94
經過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的類信息;
以佔用總內存的百分比的方式來列舉出全部的實例對象,能夠用來發現大內存對象;
如上圖所示:能夠看到ConcurrentHashMap@0x60191cfa8這個對象佔據了98.92%的堆大小,因此基本就能夠判定,當前項目之因此會down機的主要緣由是,ConcurrentHashMap溢出所致使的問題;
那麼當咱們須要查看,當前該ConcurrentHashMap@0x60191cfa8對象都引用了那些數據,以及當前該對象是被那幾個對象所引用的,如何查看?
鼠標在當前所要查看的對象右鍵,點擊List Objects能夠看到分別提供了:with outgoing references(查看當前該對象的全部的引用信息) 和 with incoming references(查看當前該對象是被那幾個對象所引用的) ;
原創聲明:做者:Arnold.zhao 博客園地址:https://www.cnblogs.com/zh94
經過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下的功能使用已經有了一個大概的瞭解,須要注意的是,Histogram 以及Dominator Tree時所主要說起的Shallow Size以及Retained Size以及在所列出的對象上右鍵查看引用關係,GCROOTS,以及左上角所展現的屬性明細等功能 是適用於全部的功能模塊的,後續再也不贅述;
查看完上述關於Overview中的功能說明後,此處再來看一下Overview中不包含的一些功能
以下圖所示,點擊一級導航欄的第5個圖標,能夠用來查看當前進程dump時的全部線程的堆棧信息,經過分析下面所對應的堆棧信息,能夠很快速的定位到對應的線程所執行的方法等層級關係,以此來定位對應的異常問題;
用於查詢Java堆的類SQL查詢語言
點擊一級導航欄的第6個圖標的下拉框下的 Heap Dump Overview,能夠查看全局的內存佔用信息
查看指定內存地址所對應的對象信息;
一、線程所引用對象溢出
二、靜態屬性對象溢出
線程棧所引用對象溢出的場景,以下:
Mat各功能內還有不少小的子功能,使用過程當中可逐步嘗試,此處再也不贅述