#頭條創作挑戰賽#
MAT 全稱 Tools 是一個分析 Java堆數據的專業工具,可以計算出內存中對象的實例數量、占用空間大小、引用關系等,看看是誰阻止了垃圾收集器的回收工作,從而定位內存泄漏的原因。
2.什么時候會用到MAT?
a)的時候,觸發Full GC,但空間卻回收不了,引發內存溢出
b)java應用服務器系統異常,比如load負載飆高,io異常,或者線程死鎖等,都可能通過分析堆中的內存對象來定位原因
3.MAT安裝:
--下載地址
-歷史版本下載
選擇平臺版本下載即可
--官網使用教程
注: Mac啟動報錯
java.lang.n: The area could not be : xxx ... By the its
under the when the is . Use the -data to
Mac啟動報錯
Mac啟動報錯fix:
mat-右鍵-顯示包內容
編輯 .ini 文件
添加一行配置: 新建 /Users/jinze/dev/MAT 目錄后
-data
/Users/jinze/dev/MAT
問題fix
#參數配置:
分析堆轉儲文件需要消耗很多的堆空間,為了保證分析的效率和性能,在有條件的情況下,建議分配給 MAT 盡可能多的內存資源。兩種方式分配內存資源給 MAT:
1)修改啟動參數 .exe - -Xmx4g
2)編輯文件 .ini 添加 - – Xmx4g
否認可能由于內存不足導致打開堆內存快照失敗
4.MAT分析dump堆棧:
#4.1dump文件生成:
a)jvm內存溢出自動生成dump內存快照
-XX:+-XX:=/home/work/.hprof
b)手動觸發生成
jps -v --查看jvm pid: 26041
生成jvm dump快照:
jmap -dump:=b,file=/home/work/jinze/.hprof 26041 --> 生成二進制堆棧文件。
jmap -heap 26041 --查看jvm堆棧內存占用情況
jmap -histo:live 26041 | head -20 --查看jvm內存占用前20存活對象
#5.MAT分析 dump文件:
基本概念:
Heap: 類對象本身占用內存大小c語言申請動態內存失敗,不包含其引用的對象內存-> List對象占用內存大小 4k
Heap:對象自己占用內存 + 關聯引用對象占用大小 -> List對象占用內存大小 4k + User對象占用內存大小 123k注:如一個持有100,000個對象,每一個占用16 bytes,移除這些可以釋放16 x 100,000 + X,X代表的大小。相對于 heap,可以更精確的反映一個對象實際占用的大小(因為如果該對象釋放, heap都可以被釋放)。
demo: List users;
Set指的是這個對象本身和他持有引用的對象以及這些引用對象的 Set所占內存大小的總和,官方的圖解如下所示。
從圖中可以看出E的 Set為E和G。C的 Set為C、D、E、F、G、H。
MAT所定義的支配樹就是從上圖的引用樹演化而來。在引用樹當中,一條到Y的路徑必然會經過X,這就是X支配Y。X直接支配Y則指的是在所有支配Y的對象中,X是Y最近的一個對象。
內存溢出排除方法思路:
1.看GC日志 ->() [回收前后內存大小不變或一直增長無減少波動,則可能有內存溢出問題]
2.生成堆內存 heap dump(某個時間點jvm中所有活躍的對象的堆內存快照)
3.MAT查看: 過濾列舉對象(傳入或傳出的對象引用)、分組排序顯示
1. or : Heap倒敘排序 查看內存占用
2. 定位問題代碼段: 看有沒有GC Root指向:若無GC Root指向 -> Merge Paths to GC Roots -> all /weak/soft etc.(排除虛弱軟引用) ->查找GC Root線程
File > Open Heap Dump > Leak -打開dump文件
> > The (查看堆棧中java類 對象[]個數、[ Heap] 此類對象占用大小、[ Heap]關聯對象占用大小) -> Heap倒敘排序(重點關注內存占用高對象) -> Merge Paths to GC roots -> all /weak/soft etc.(排除所有虛弱軟引用) ->查看剩余未被回收的強引用對象占用原因 & GC Roots。
> > (查看堆中內存占用最高的對象的線程調用堆棧) -> 對象調用堆棧樹-查找內存占用最高對象( Heap倒敘排序) -> Paths to GC Roots -> all /weak/soft etc.(排除所有虛弱軟引用) -查找GC Root線程 -> 查找未釋放的內存占用最高的代碼邏輯段(很可能是產生內存溢出代碼)
MAT分析dump具體步驟如下:##1.MAT打開dump文件:
MAT打開dump文件,生成分析報告: File > Open Heap Dump > Leak
Open Heap Dump
Leak - -分析內存泄漏可疑點
1.
概要信息,比如空間大小、類的數量、對象實例數量、類加載器等等
里面提供了多種分析維度: (重點關注 & Tree 即可)
按類列出內存中的對象,對象的個數以及大小。
Tree 支配樹,分析對象的引用關系。
Leak 通過MA自動分析泄漏的原因。
##2.
> > The (查看堆棧中java類對象[]個數、[ Heap] 此類對象占用大小、[ Heap]關聯對象占用大小)
按類列出所有實例對象個數、 Heap(對象本身占用內存大小)、 Heap(對象本身占用內存大小+關聯引用對象占用內存) 內存占用情況,可以通過Class Name過濾篩選 ;or 按照對象 或 class 引用 和 被引用 展示: List or Show by class: [with 列出哪些類引入該類;with 出該類引用了哪些類]
> The (查看堆棧中java類 對象[]個數、[ Heap] 此類對象占用大小、[ Heap]關聯對象占用大小) -> Heap倒敘排序(重點關注內存占用高對象) -> Merge Paths to GC roots -> all /weak/soft etc.(排除所有虛弱軟引用) ->查看剩余未被回收的強引用對象占用原因 & GC Roots。
## 3. Tree
支配樹,分析對象的引用關系。 對象內存占用&占比
-> 對象調用堆棧樹-查找內存占用最高對象( Heap倒敘排序) -> Paths to GC Roots -> all /weak/soft etc.(排除所有虛弱軟引用) -查找GC Root線程-> 定位未釋放內存代碼段
> (查看堆中內存占用最高的對象的線程調用堆棧) -> 對象調用堆棧樹-查找內存占用最高對象( Heap倒敘排序) -> Paths to GC Roots -> all /weak/soft etc. (排除所有虛弱軟引用) -查找GC Root線程 -> 查找未釋放的內存占用最高的代碼邏輯段(很可能是產生內存溢出代碼)
##4.Leak --自動分析內存溢出可疑點
MAT插件會給出一份可疑的分析報告,非常方便,我們只需結合源代碼稍加分析到底哪個才是引發問題真正原因所在。點點看c語言申請動態內存失敗,若有問題你很容易發現你熟悉的代碼段。
##5.OQL:
OQL全稱為 Query ,類似于SQL語句的查詢語言,能夠用來查詢當前內存中滿足指定條件的所有的對象。
API:
##6. 對比dump 堆棧文件
因為我們這個例子很簡單,可以通過上面的方法來找到內存泄漏的原因,但是復雜的情況就需要通過對比hpof文件來進行分析了。使用步驟為:
操作應用,生成第一個hpof文件。
進行一段時間操作,再生成第二個hpof文件。
用MAT打開這兩個hpof文件。
將第一個和第二個hpof文件的 Tree或者添加到 中,之后選中2個文件對比即可
2個dump文件對比尋找波動差異(關注差異波動大的對象)
參考:
#JVM# #JVM內存問題定位# #java虛擬機內存溢出# #java虛擬機內存泄漏排障#