MAT使用-jvm內存溢出問題分析定位

1.MAT簡介:

MAT 全稱 Eclipse Memory Analysis Tools 是一個分析 Java堆數據的專業工具,能夠計算出內存中對象的實例數量、佔用空間大小、引用關係等,看看是誰阻止了垃圾收集器的回收工做,從而定位內存泄漏的緣由。php

 


2.何時會用到MAT?

a)OutOfMemoryError的時候,觸發full gc,但空間卻回收不了,引起內存泄露html

b)java服務器系統異常,好比load飆高,io異常,或者線程死鎖等,均可能經過分析堆中的內存對象來定位緣由java


3.MAT安裝:

https://www.eclipse.org/mat/downloads.php --下載地址服務器

http://help.eclipse.org/oxygen/index.jsp?topic=/org.eclipse.mat.ui.help/welcome.html --官網使用教程app

#參數配置:dom

分析堆轉儲文件須要消耗不少的堆空間,爲了保證分析的效率和性能,在有條件的狀況下,建議分配給 MAT 儘量多的內存資源。兩種方式分配內存資源給 MAT:eclipse

1)修改啓動參數 MemoryAnalyzer.exe -vmargs -Xmx4gjvm

2)編輯文件 MemoryAnalyzer.ini 添加 -vmargs – Xmx4gjsp

 


4.MAT分析dump堆棧:

#4.1dump文件生成:工具

a)jvm內存溢出OutOfMemoryError自動生成dump內存快照

-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=/home/work/oom_error.hprof

b)手動觸發生成

jps -v --查看jvm pid: 26041

生成jvm dump快照:

jmap -dump:format=b,file=/home/work/jinze/dump_26041_05231438.hprof 26041 --> 生成二進制堆棧文件。

jmap -heap 26041 --查看jvm堆棧內存佔用狀況

jmap -histo:live 26041 | head -20  --查看jvm內存佔用前20存活對象

#5.MAT分析 dump文件:

基本概念:

Shallow Heap: 類對象自己佔用內存大小,不包含其引用的對象內存-> List對象佔用內存大小 4k

Retained Heap: 對象本身佔用內存 + 關聯引用對象佔用大小 -> List對象佔用內存大小 4k + User對象佔用內存大小 123k注:如一個ArrayList持有100,000個對象,每個佔用16 bytes,移除這些ArrayList能夠釋放16 x 100,000 + X,X表明ArrayList的shallow大小。相對於shallow heap,RetainedHeap能夠更精確的反映一個對象實際佔用的大小(由於若是該對象釋放,retained heap均可以被釋放)。

demo: private List<User> users;

Retained Set指的是這個對象自己和他持有引用的對象以及這些引用對象的Retained Set所佔內存大小的總和,官方的圖解以下所示。

 

 

從圖中能夠看出E的Retained Set爲E和G。C的Retained Set爲C、D、E、F、G、H。

MAT所定義的支配樹就是從上圖的引用樹演化而來。在引用樹當中,一條到Y的路徑必然會通過X,這就是X支配Y。X直接支配Y則指的是在全部支配Y的對象中,X是Y最近的一個對象。

 

內存溢出排除方法思路: 

1.看GC日誌  126719K->126719K(126720K) [回收先後內存大小不變或一直增加無減小波動,則可能有內存溢出問題]

2.生成堆內存 heap dump(某個時間點jvm中全部活躍的對象的堆內存快照)

3.MAT查看: 過濾列舉對象(傳入或傳出的對象引用)、分組排序顯示

1. Histogram  or dominator_tree: Retained Heap倒敘排序 查看內存佔用 

2. 定位問題代碼段:  看有沒有GC Root指向:若無GC Root指向 -> Merge Shortest Paths to GC Roots -> exclude all phantom/weak/soft etc.reference(排除虛弱軟引用) ->查找GC Root線程

File > Open Heap Dump > Leak Suspects Report  -打開dump文件

Overview > Actions > The Histogram (查看堆棧中java類 對象[Objects]個數、[Shallow Heap]individual objects此類對象佔用大小、[Retained Heap]關聯對象佔用大小) -> Retained Heap倒敘排序(重點關注內存佔用高對象) ->  Merge Shortest Paths to GC roots ->  exclude all phantom/weak/soft etc.reference(排除全部虛弱軟引用) ->查看剩餘未被回收的強引用對象佔用緣由 & GC Roots。

Overview > Actions > dominator_tree (查看堆中內存佔用最高的對象的線程調用堆棧) dominator_tree -> 對象調用堆棧樹-查找內存佔用最高對象(Retained Heap倒敘排序) ->  Paths to GC Roots -> exclude all phantom/weak/soft etc.reference (排除全部虛弱軟引用) -查找GC Root線程 -> 查找未釋放的內存佔用最高的代碼邏輯段(極可能是產生內存溢出代碼)

MAT分析dump具體步驟以下:

##1.MAT打開dump文件:

MAT打開dump文件,生成分析報告: File > Open Heap Dump > Leak Suspects Report 

 

Open Heap Dump 

 

Leak Suspects Report - Finish -分析內存泄漏可疑點

1.Overview

Overview概要信息,好比空間大小、類的數量、對象實例數量、類加載器等等

Atcion裏面提供了多種分析維度: (重點關注 Histogram & Dominator Tree  便可

Histogram 按類列出內存中的對象,對象的個數以及大小。

Dominator Tree 支配樹,分析對象的引用關係。

Leak Suspects經過MA自動分析泄漏的緣由。

Overview

##2.Histogram 

Overview > Actions > The Histogram (查看堆棧中java類對象[Objects]個數、[Shallow Heap]individual objects此類對象佔用大小、[Retained Heap]關聯對象佔用大小)

按類列出全部實例對象個數Objects、Shallow Heap(對象自己佔用內存大小)、Retained Heap (對象自己佔用內存大小+關聯引用對象佔用內存) 內存佔用狀況,能夠經過Class Name過濾篩選 ;or  按照對象 或 class 引用 和 被引用 展現:   List objects  or Show objects by class: [with incoming references 列出哪些類引入該類;with outgoing references 出該類引用了哪些類]

 Actions > The Histogram (查看堆棧中java類 對象[Objects]個數、[Shallow Heap]individual objects此類對象佔用大小、[Retained Heap]關聯對象佔用大小) -> Retained Heap倒敘排序(重點關注內存佔用高對象) ->  Merge Shortest Paths to GC roots -> exclude all phantom/weak/soft etc.reference(排除全部虛弱軟引用) ->查看剩餘未被回收的強引用對象佔用緣由 & GC Roots。

 

## 3.Dominator Tree

支配樹,分析對象的引用關係。 對象內存佔用&佔比 

dominate_tree -> 對象調用堆棧樹-查找內存佔用最高對象(Retained Heap倒敘排序) ->  Paths to GC Roots -> exclude all phantom/weak/soft etc.reference(排除全部虛弱軟引用) -查找GC Root線程-> 定位未釋放內存代碼段

Actions > dominator_tree (查看堆中內存佔用最高的對象的線程調用堆棧) -> 對象調用堆棧樹-查找內存佔用最高對象(Retained Heap倒敘排序) ->  Paths to GC Roots -> exclude all phantom/weak/soft etc.reference (排除全部虛弱軟引用) -查找GC Root線程 -> 查找未釋放的內存佔用最高的代碼邏輯段(極可能是產生內存溢出代碼)

##4.Leak Suspects --自動分析內存溢出可疑點

MAT插件會給出一份可疑的分析報告,很是方便,咱們只需結合源代碼稍加分析到底哪一個Problem纔是引起問題真正緣由所在。點點看 Details,如有問題你很容易發現你熟悉的代碼段。

 

##5.OQL:

OQL全稱爲Object Query Language,相似於SQL語句的查詢語言,可以用來查詢當前內存中知足指定條件的全部的對象。

API: http://help.eclipse.org/luna/index.jsp?topic=/org.eclipse.mat.ui.help/reference/oqlsyntax.html

##6. 對比dump 堆棧文件

由於咱們這個例子很簡單,能夠經過上面的方法來找到內存泄漏的緣由,可是複雜的狀況就須要經過對比hpof文件來進行分析了。使用步驟爲:

操做應用,生成第一個hpof文件。

進行一段時間操做,再生成第二個hpof文件。

用MAT打開這兩個hpof文件。

將第一個和第二個hpof文件的Dominator Tree或者Histogram添加到Compare Basket中,以後選中2個文件對比便可

 

 

2個dump文件對比尋找波動差別(關注差別波動大的對象)


參考:

https://blog.csdn.net/itomge/article/details/48719527

https://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-ma/index.html

http://liuwangshu.cn/application/performance/ram-5-mat.html

相關文章
相關標籤/搜索