34-內(nèi)存泄露MAT工具看本文就夠了

一. 簡介

歡迎關(guān)注公眾號(hào)OpenCoder眉抬,來和我做朋友吧~

Eclipse Memory Analyzer是一個(gè)快速且功能豐富的Java堆分析器夜赵,可幫助您查找內(nèi)存泄漏并減少內(nèi)存消耗。使用Memory Analyzer分析具有數(shù)億個(gè)對(duì)象的高效堆轉(zhuǎn)儲(chǔ),快速計(jì)算對(duì)象的保留大小,查看誰阻止垃圾收集器收集對(duì)象侠姑,運(yùn)行報(bào)告以自動(dòng)提取泄漏嫌疑者。

通過MAT工具箩做,可以做以下幾方面的事兒:

  • 找到最大的對(duì)象莽红,因?yàn)?MAT 提供了合理的累積大小(retained size)
  • 探索對(duì)象圖邦邦,包括入站和出站引用
  • 計(jì)算從GC Roots 到有趣對(duì)象的路徑
  • 查找內(nèi)存浪費(fèi)安吁,如冗余 String 對(duì)象、空集合對(duì)象等...

二.下載地址

https://www.eclipse.org/mat/downloads.php

image

目前絕大多數(shù)開發(fā)工具都已經(jīng)使用IDEA了燃辖,因此大家下載獨(dú)立的MAT即可鬼店,注意:獨(dú)立的MAT運(yùn)行需要在JDK11及以上的環(huán)境。

三.Heap Dump

首先了解下Heap Dump,它也叫堆轉(zhuǎn)儲(chǔ)文件黔龟,是java進(jìn)程在某個(gè)時(shí)間內(nèi)的快照妇智。它在觸發(fā)快照的時(shí)候保存了很多信息:java對(duì)象和類信息。通常情況下捌锭,在寫入堆轉(zhuǎn)儲(chǔ)之前會(huì)觸發(fā)完整的 GC俘陷,因此它包含有關(guān)剩余對(duì)象的信息罗捎。

Memory Analyzer 能夠處理來自各種平臺(tái)的 HPROF 二進(jìn)制堆轉(zhuǎn)儲(chǔ)观谦、IBM 系統(tǒng)轉(zhuǎn)儲(chǔ)(舊版本需要預(yù)處理)和 IBM 便攜式堆轉(zhuǎn)儲(chǔ) (PHD)。

在Heap Dump中能得到的信息包括:(以下摘自官網(wǎng))

Typical information which can be found in heap dumps (depending on the heap dump type):

  • All Objects

    Class, fields, primitive values and references

  • All Classes

    Classloader, name, super class, static fields

  • Garbage Collection Roots

    Objects defined to be reachable by the JVM

  • Thread Stacks and Local Variables

    The call-stacks of threads at the moment of the snapshot, and per-frame information about local objects

這里給大家翻譯一下為:

可以在堆轉(zhuǎn)儲(chǔ)中找到的典型信息(取決于堆轉(zhuǎn)儲(chǔ)類型):

  • 所有對(duì)象
    類桨菜、字段豁状、原始值和引用

  • All Classes

    類加載器、名稱倒得、超類泻红、靜態(tài)字段

  • 垃圾收集根對(duì)象GC Roots
    定義為可由 JVM 訪問的對(duì)象(比如:局部變量和類靜態(tài)變量)

  • 線程棧和局部變量
    快照時(shí)刻線程的調(diào)用堆棧,以及有關(guān)本地對(duì)象的每幀信息

四.怎樣獲取Dump

Dump文件的格式為:HPROF霞掺,內(nèi)存分析器可以處理HPROF 二進(jìn)制格式的堆轉(zhuǎn)儲(chǔ)

那么我們可以從以下幾方面來獲取Dump文件:

  • Non-interactive 被動(dòng)獲纫曷贰:

    通過OOM獲取,即在OutOfMemoryError后獲取一份HPROF二進(jìn)制Heap Dump文件菩彬,可以在jvm里添加參數(shù):(除非真正發(fā)生 OOM缠劝,否則不涉及任何開銷)

    -XX:+HeapDumpOnOutOfMemoryError
    

    這個(gè)參數(shù)對(duì)于生產(chǎn)系統(tǒng)來說是必須的,因?yàn)樗ǔJ沁M(jìn)一步分析內(nèi)存泄露問題的唯一方法骗灶。

    默認(rèn)情況下惨恭,堆轉(zhuǎn)儲(chǔ)將在 JVM 的“當(dāng)前目錄”中生成。它可以使用-XX:HeapDumpPath=顯式重定向耙旦,例如-XX:HeapDumpPath=/disk2/dumps脱羡。請(qǐng)注意,轉(zhuǎn)儲(chǔ)文件可能很大,可達(dá)千兆字節(jié)锉罐,因此請(qǐng)確保目標(biāo)文件系統(tǒng)有足夠的空間帆竹。

  • Interactive 主動(dòng)獲取

    1. 在虛擬機(jī)中添加參數(shù)如下,然后在Ctrl+Break組合鍵即可獲取一份Heap Dump:

      -XX:+HeapDumpOnCtrlBreak
      
  1. 通過 jmap 工具生成脓规,在命令行中輸入:

    jmap -dump:format=b file=<文件名XX.hprof> <pid>
    
  2. Sun JConsole:啟動(dòng) jconsole.exe 并在 HotSpotDiagnostic MBean 上調(diào)用操作 dumpHeap()

  3. 使用Memory Analyzer Tools的File -> Acquire Heap Dump功能

image

圖形化界面操作馆揉,直接選擇想要dump的pid進(jìn)程,設(shè)置存放文件的路徑即可抖拦。

五.MAT使用

準(zhǔn)備一份dump文件升酣,通過MAT工具進(jìn)行打開,在選好文件后态罪,會(huì)讓你選一下報(bào)告類型噩茄,默認(rèn)是內(nèi)存泄漏探測(cè)報(bào)告,沒有什么特殊情況下复颈,選它就可以了:

image

內(nèi)存泄漏可疑點(diǎn)(Leak Suspects)

進(jìn)入MAT后會(huì)展示內(nèi)存泄漏可疑點(diǎn)在內(nèi)存中的分布情況绩聘,還會(huì)列出具體的類,如果是自己的代碼耗啦,基本上一眼大概就能定位到某些業(yè)務(wù)凿菩,如果還不能肯定,也沒關(guān)系帜讲,接下來還有很多功能可以輔助分析

image

上圖中Problem Suspect1 即代表可能出現(xiàn)內(nèi)存泄露的問題分析:

The thread java.lang.Thread @ 0xff626d38 main keeps local variables with total size 7,293,920 (89.25%) bytes.

在線程的main中持續(xù)引用本地變量達(dá)到了 7.3M的內(nèi)存衅谷,占用堆內(nèi)存89.25%

The memory is accumulated in one instance of java.lang.Object[], loaded by <system class loader>, which occupies 7,292,936 (89.24%) bytes.

內(nèi)存累積在一個(gè)“java.lang.Object[]”實(shí)例中,由“<system class loader>”加載似将,占用7,292,936 (89.24%)字節(jié)获黔。說明的非常清晰,這個(gè)數(shù)組占據(jù)了大量的內(nèi)存在验。

那么這個(gè)數(shù)組里到底是什么東西呢玷氏?

在上圖中的左下角大家看到有一個(gè) Details,大家點(diǎn)進(jìn)去即可看到詳細(xì)的說明:

image

通過Details我們可以看到腋舌,在主線程的下方引用了一個(gè) java.util.ArrayList, 這里面是一個(gè)java.lang.Object[]數(shù)組盏触,通過這里我們既可以清楚到底是什么對(duì)象占用了過大的內(nèi)存,所以MAT分析內(nèi)存是非常方便的块饺。

六.追蹤線程執(zhí)行堆棧赞辩,找到問題代碼

一旦發(fā)現(xiàn)在某個(gè)線程執(zhí)行過程中創(chuàng)建了大量對(duì)象之后,就可以嘗試找這個(gè)線程到底執(zhí)行了哪些代碼才創(chuàng)建了這些對(duì)象刨沦,我們可以點(diǎn)擊下圖中的“See stacktrace”

image

點(diǎn)擊進(jìn)去后即準(zhǔn)確找到了發(fā)生問題的代碼行數(shù):

image

這里我們貼出對(duì)應(yīng)的源代碼诗宣,其實(shí)非常簡單,如下:

image

代碼問題就出現(xiàn)在了第10行想诅,list添加元素這兒召庞。

七. Histogram

剛才我們是在Leak Suspects中進(jìn)行分析的岛心,另外我們還可以打開一個(gè)非常常用的工具:Histogram

image

點(diǎn)擊進(jìn)去:

image

這里每一列的參數(shù)做一個(gè)解釋:

  • Class Name : 類名稱,java類名
  • Objects : 類的對(duì)象的數(shù)量篮灼,這個(gè)對(duì)象被創(chuàng)建了多少個(gè)
  • Shallow Heap :一個(gè)對(duì)象內(nèi)存的消耗大小忘古,不包含對(duì)其他對(duì)象的引用
  • Retained Heap :是shallow Heap的總和,也就是該對(duì)象被GC之后所能回收到內(nèi)存的總和

可以看到Object[]這個(gè)數(shù)組就占據(jù)了7.4MB.

在某一項(xiàng)上右鍵打開菜單選擇 list objects ->with incoming refs 將列出該類的實(shí)例:

image
image

大家可以發(fā)現(xiàn)通過這種方式也是能直觀找到我們的大對(duì)象到底是什么诅诱。

好了髓堪,相信通過本篇文章的講解,大家對(duì)于MAT工具的使用有了一定的理解和參考娘荡,后續(xù)遇到內(nèi)存泄露干旁、內(nèi)存卡頓、大對(duì)象數(shù)據(jù)分析都可以直接通過MAT精準(zhǔn)確定炮沐,更好的優(yōu)化我們的項(xiàng)目争群。

歡迎關(guān)注公眾號(hào)OpenCoder,來和我做朋友吧~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末大年,一起剝皮案震驚了整個(gè)濱河市换薄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌翔试,老刑警劉巖轻要,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異垦缅,居然都是意外死亡冲泥,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門失都,熙熙樓的掌柜王于貴愁眉苦臉地迎上來柏蘑,“玉大人幸冻,你說我怎么就攤上這事粹庞。” “怎么了洽损?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵庞溜,是天一觀的道長。 經(jīng)常有香客問我碑定,道長流码,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任延刘,我火速辦了婚禮漫试,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘碘赖。我一直安慰自己驾荣,他們只是感情好外构,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著播掷,像睡著了一般审编。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上歧匈,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天垒酬,我揣著相機(jī)與錄音,去河邊找鬼件炉。 笑死勘究,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的斟冕。 我是一名探鬼主播乱顾,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼宫静!你這毒婦竟也來了走净?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤孤里,失蹤者是張志新(化名)和其女友劉穎伏伯,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捌袜,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡说搅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了虏等。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弄唧。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖霍衫,靈堂內(nèi)的尸體忽然破棺而出候引,到底是詐尸還是另有隱情,我是刑警寧澤敦跌,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布澄干,位于F島的核電站,受9級(jí)特大地震影響柠傍,放射性物質(zhì)發(fā)生泄漏麸俘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一惧笛、第九天 我趴在偏房一處隱蔽的房頂上張望从媚。 院中可真熱鬧,春花似錦患整、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迈着。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工父阻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人望抽。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓加矛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親煤篙。 傳聞我的和親對(duì)象是個(gè)殘疾皇子斟览,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容