日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

mat分析dump分析_MAT从入门到精通(一)

發(fā)布時間:2025/3/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mat分析dump分析_MAT从入门到精通(一) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

盡管JVM提供了自動內(nèi)存管理的機制,試圖降低程序員的開發(fā)門檻,確實也實現(xiàn)了這一目標,在日常開發(fā)中,我們一般都不需要關(guān)心對象的內(nèi)存釋放。JVM大部分都是使用trace算法來判斷一個對象是否該被回收,那么JVM只能回收那些從gc roots不可達的對象。

如果我們在使用某些大的對象、集合對象或者一些三方包里的資源,忘記及時釋放資源的話,還是會造成JVM的內(nèi)存泄漏或內(nèi)存浪費的問題。因此,如果想成為更高階的Java開發(fā)工程師,我們需要了解常見的問題排查的辦法和工具,這個系列的文章,準備介紹一個用來做JVM堆內(nèi)存分析的工具——MAT(Memory Aanlysis Tool)。

MAT的官網(wǎng)在:https://www.eclipse.org/mat/,可以看下它的介紹——MAT是一款高性能、具備豐富功能的Java堆內(nèi)存分析工具,可以用來排查內(nèi)存泄漏和內(nèi)存浪費的問題。

一、安裝和裝設(shè)置

1.1 mac安裝

MAT 支持兩種安裝方式,一種是"單機版“的,也就是說用戶不必安裝 Eclipse IDE 環(huán)境,MAT 作為一個獨立的 Eclipse RCP 應(yīng)用運行;另一種是”集成版“的,也就是說 MAT 也可以作為 Eclipse IDE 的一部分,和現(xiàn)有的開發(fā)平臺集成。

這里我們考慮獨立安裝,在觀望的下載頁面,選擇mac os版本的安裝文件下載即可。

安裝遇到的坑

  • 啟動直接報錯,系統(tǒng)默認的workspace是只讀的,更換掉即可。怎么更換呢,在文件/Applications/mat.app/Contents/Eclipse/MemoryAnalyzer.ini中進行修改。
  • 啟動后,UI界面沒反應(yīng),參考:https://www.eclipse.org/forums/index.php/t/1090889/,換個包即可。這個問題我遇到過很多次。
  • 1.2 mat的設(shè)置

    配置mat的堆內(nèi)存大小

    我的電腦是8C16G的,那理論上分析10G的堆文件沒問題,但是MAT默認的配置沒有這么大,需要在/Applications/mat.app/Contents/Eclipse/MemoryAnalyzer.ini文件中進行修改。如下圖所示,我將我的MAT自己的運行時堆內(nèi)存配置成了6G。

    配置MAT的使用

    MAT的配置頁面可以從Window——>Preferences找到,如下圖所示。

    MAT的一般配置有幾個選項

  • Keep unreachable objects:如果勾選這個,則在分析的時候會包含dump文件中的不可達對象;
  • Hide the getting started wizard:隱藏分析完成后的首頁,控制是否要展示一個對話框,用來展示內(nèi)存泄漏分析、消耗最多內(nèi)存的對象排序。
  • Hide popup query help:隱藏彈出查詢幫助,除非用戶通過F1或Help按鈕查詢幫助。
  • Hide Welcome screen on launch:隱藏啟動時候的歡迎界面
  • Bytes Display:設(shè)置分析結(jié)果中內(nèi)存大小的展示單位
  • 可以看出,MAT不僅支持HPROF文件的分析,還支持DTFJ文件的分析。一般sun公司系列的JVM生成的dump文件都是HPROF格式的,IBM的JVM生成的dump文件時DTFJ格式的。

    二、基本概念

    Heap Dump

    Heap Dump是Java進程在某個時刻的內(nèi)存快照,不同JVM的實現(xiàn)的Heap Dump的文件格式可能不同,進而存儲的數(shù)據(jù)也可能不同,但是一般來說。

    Heap Dump中主要包含當生成快照時堆中的java對象和類的信息,主要分為如下幾類:

    • 對象信息:類名、屬性、基礎(chǔ)類型和引用類型
    • 類信息:類加載器、類名稱、超類、靜態(tài)屬性
    • gc roots:JVM中的一個定義,進行垃圾收集時,要遍歷可達對象的起點節(jié)點的集合
    • 線程棧和局部變量:快照生成時候的線程調(diào)用棧,和每個棧上的局部變量

    Heap Dump中沒有包含對象的分配信息,因此它不能用來分析這種問題:一個對象什么時候被創(chuàng)建、一個對象時被誰創(chuàng)建的。

    Shallow vs. Retained Heap

    Shallow heap是一個對象本身占用的堆內(nèi)存大小。一個對象中,每個引用占用8或64位,Integer占用4字節(jié),Long占用8字節(jié)等等。

    Retained set,對于某個對象X來說,它的Retained set指的是——如果X被垃圾收集器回收了,那么這個集合中的對象都會被回收,同理,如果X沒有被垃圾收集器回收,那么這個集合中的對象都不會被回收。

    Retained heap,對象X的Retained heap指的時候它的Retained set中的所有對象的Shallow si的和,換句話說,Retained heap指的是對象X的保留內(nèi)存大小,即由于它的存活導(dǎo)致多大的內(nèi)存也沒有被回收。

    leading set,對象X可能不止有一個,這些對象統(tǒng)一構(gòu)成了leading set。如果leading set中的對象都不可達,那么這個leading set對應(yīng)的retained set中的對象就會被回收。一般有以下幾種情況:

  • 某個類的所有實例對象,這個類對象就是leading object
  • 某個類記載器加載的所有類,以及這些類的實例對象,這個類加載器對象就是leading object
  • 一組對象,要達到其他對象的必經(jīng)路徑上的對象,就是leading object
  • 在下面這張圖中,A和B是gc roots中的節(jié)點(方法參數(shù)、局部變量,或者調(diào)用了wait()、notify()或synchronized()的對象)等等。可以看出,E的存在,會導(dǎo)致G無法被回收,因此E的Retained set是E和G;C的存在,會導(dǎo)致E、D、F、G、H都無法被回收,因此C的Retined set是C、E、D、F、G、H;A和B的存在,會導(dǎo)致C、E、D、F、G、H都無法被回收,因此A和B的Retained set是A、B、C、E、D、F、G、H。

    Dominator Tree

    MAT根據(jù)堆上的對象引用關(guān)系構(gòu)建了支配樹(Dominator Tree),通過支配樹可以很方便得識別出哪些對象占用了大量的內(nèi)存,并可以看到它們之間的依賴關(guān)系。

    如果在對象圖中,從gc root或者x上游的一個節(jié)點開始遍歷,x是y的必經(jīng)節(jié)點,那么就可以說x支配了y(dominate)。

    如果在對象圖中,x支配的所有對象中,y的距離最近,那么就可以說x直接支配(immediate dominate)y。

    支配樹是基于對象的引用關(guān)系圖建立的,在支配樹中每個節(jié)點都是它的子節(jié)點的直接支配節(jié)點。基于支配樹可以很清楚得看到對象之間的依賴關(guān)系。

    現(xiàn)在看個例子,在下面這張圖中

  • x節(jié)點的子樹就是所有被x支配的節(jié)點集合,也正式x的retained set;
  • 如果x是y的直接支配節(jié)點,那么x的支配節(jié)點也可以支配y
  • 支配樹中的邊跟對象引用圖中的引用關(guān)系并不是一一對應(yīng)的。
  • Garbage Collection Roots

    在MAT中,gc roots的概念跟研究垃圾收集算法時候的概念稍微有點不同。gc roots中的對象,是指那些可以從堆外訪問到的對象的集合。如果一個對象符合下面這些場景中的一個,就可以被認為是gc roots中的節(jié)點:

  • System Class:由bootstrap classloader加載的類,例如rt.jar,里面的類的包名都是java.util.*開頭的。
  • JNI Local:native代碼中的局部變量,例如用戶編寫的JNI代碼或JVM內(nèi)部代碼。
  • JNI Global:native代碼中的全局變量,例如用戶編寫的JNI代碼或JVM內(nèi)部代碼。
  • Thread Block:被當前活躍的線程鎖引用的對象。
  • Thread:正在存活的線程
  • Busy Monitor:調(diào)用了wait()、notify()或synchronized關(guān)鍵字修飾的代碼——例如synchronized(object)或synchronized方法。
  • Java Local:局部變量。例如函數(shù)的輸入?yún)?shù)、正在運行的線程棧里創(chuàng)建的對象。
  • Native Stack:native代碼的輸入或輸出參數(shù),例如用戶定義的JNI代碼或JVM的內(nèi)部代碼。在文件/網(wǎng)絡(luò)IO方法或反射方法的參數(shù)。
  • Finalizable:在finalize隊列中等待它的finalizer對象運行的對象。
  • Unfinalized:重載了finalize方法,但是還沒有進入finalize隊列中的對象。
  • Unreachable:從任何gc roots節(jié)點都不可達的對象,在MAT中將這些對象視為root節(jié)點,如果不這么做,就不能對這些對象進行分析。
  • Java Stack Frame:Java棧幀,用于存放局部變量。只在dump文件被解析的時候會將java stack frame視為對象。
  • Unknown:沒有root類型的對象。有些dump文件(例如IBM的Portable Heap Dump)沒有root信息。
  • 三、獲取Dump文件

  • 通過MAT生成dump文件 通過這個路徑找到生成dump文件的對話框
  • 選擇一個進程,點擊finish即可

  • 通過jmap命令生成dump文件
    • 命令格式:jmap -dump:live,format=b,file=heap.bin <pid>
    • 注意:如果要保留heapdump中的不可達對象,則需要把”:live“去掉,即使用命令”jmap -dump,format=b,file=heap.bin <pid>“
  • 通過設(shè)置JVM參數(shù)自動生成 使用-XX:+HeapDumpOnOutOfMemoryError這個JVM參數(shù),在Java進程運行過程中發(fā)生OOM的時候就會生成一個heapdump文件,并寫入到指定目錄,一般用-XX:HeapDumpPath=${HOME}/logs/test來設(shè)置。

  • 本號專注于后端技術(shù)、JVM問題排查和優(yōu)化、Java面試題、個人成長和自我管理等主題,為讀者提供一線開發(fā)者的工作和成長經(jīng)驗,期待你能在這里有所收獲。

    創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

    總結(jié)

    以上是生活随笔為你收集整理的mat分析dump分析_MAT从入门到精通(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。