溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用JVM內存分析工具MAT

發(fā)布時間:2021-10-25 16:49:41 來源:億速云 閱讀:231 作者:iii 欄目:編程語言

本篇內容介紹了“如何使用JVM內存分析工具MAT”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

1 簡介

MAT 是一款非常強大的內存分析工具,在 Eclipse 中有相應的插件,同時也有單獨的安裝包。在進行內存分析時,只要獲得了反映當前設備內存映像的 hprof 文件,通過 MAT 打開就可以直觀地看到當前的內存信息。

2 使用

2.1 準備 MAT

下載獨立版本的 MAT,下載地址:https://www.eclipse.org/mat/downloads.php,下載后解壓。找到 MemoryAnalyzer.ini 文件,該文件里面有個 Xmx 參數,該參數表示最大內存占用量,默認為 1024m,根據堆轉儲文件大小修改該參數即可。

2.2 準備堆轉儲文件(Heap Dump)

堆轉儲文件(Heap Dump)是 Java 進程在某個時間內的快照(.hprof 格式)。它在觸發(fā)快照的時候保存了很多信息,如:Java 對象和類信息(通常在寫堆轉儲文件前會觸發(fā)一次 Full GC)。

堆轉儲文件信息:

如何使用JVM內存分析工具MAT

  • 所有的對象信息,包括對象實例、成員變量、存儲于棧中的基本類型值和存儲于堆中的其他對象的引用值。

  • 所有的類信息,包括 classloader、類名稱、父類、靜態(tài)變量等。

  • GC Root 到所有的這些對象的引用路徑。

  • 線程信息,包括線程的調用棧及此線程的線程局部變量(TLS)。

多種方式獲取堆轉儲文件:

  • 通過 jmap 命令可以在 cmd 里執(zhí)行:jmap -dump:format=b,file=<文件名.hprof> <pid>。

  • 如果想在發(fā)生內存溢出的時候自動 dump,需要添加下面 JVM 參數:-XX:+HeapDumpOnOutOfMemoryError。

  • 使用 Ctrl+Break 組合鍵主動獲取獲取,需要添加下面 JVM 參數:-XX:+HeapDumpOnCtrlBreak

  • 使用 HPROF Agent 可以在程序執(zhí)行結束時或受到 SIGOUT 信號時生成 Dump 文件,配置在虛擬機的參數如下:-agentlib:hprof=heap=dump,format=b

  • 使用 JConsole 獲取。

  • 使用 Memory Analyzer Tools 的 File -> Acquire Heap Dump 功能獲取。

2.3 分析堆轉儲文件

打開 MAT 之后,加載 dump 文件,差不多就下面這樣的界面:

如何使用JVM內存分析工具MAT

常用的兩個功能:Histogram、 Leak Suspects

2.3.1 Histogram

如何使用JVM內存分析工具MAT

Histogram 可以列出內存中的對象,對象的個數及其內存大小,可以用來定位哪些對象在 Full GC 之后還活著,哪些對象占大部分內存。

  • Class Name:類名稱,Java 類名。

  • Objects:類的對象的數量,這個對象被創(chuàng)建了多少個。

  • Shallow Heap:對象本身占用內存的大小,不包含其引用的對象內存,實際分析中作用不大。常規(guī)對象(非數組)的 Shallow Size 由其成員變量的數量和類型決定。數組的 Shallow Size 由數組元素的類型(對象類型、基本類型)和數組長度決定。對象成員都是些引用,真正的內存都在堆上,看起來是一堆原生的 byte[], char[], int[],對象本身的內存都很小。

  • Retained Heap:計算方式是將 Retained Set(當該對象被回收時那些將被 GC 回收的對象集合)中的所有對象大小疊加?;蛘哒f,因為 X 被釋放,導致其它所有被釋放對象(包括被遞歸釋放的)所占的 heap 大小。Retained Heap 可以更精確的反映一個對象實際占用的大小。

Retained Heap 例子:一個 ArrayList 對象持有 100 個對象,每一個占用 16 bytes,如果這個 list 對象被回收,那么其中 100 個對象也可以被回收,可以回收 16*100 + X 的內存,X 代表 ArrayList 的 shallow 大小。


如何使用JVM內存分析工具MAT

在上述列表中選擇一個 Class,右鍵選擇 List objects > with incoming references,在新頁面會顯示通過這個 class 創(chuàng)建的對象信息。


如何使用JVM內存分析工具MAT

繼續(xù)選擇一個對象,右鍵選擇 Path to GC Roots > **** ,通常在排查**內存泄漏(一般是因為存在無效的引用)**的時候,我們會選擇 exclude all phantom/weak/soft etc.references,意思是查看排除虛引用/弱引用/軟引用等的引用鏈,因為被虛引用/弱引用/軟引用的對象可以直接被 GC 給回收,我們要看的就是某個對象否還存在 Strong 引用鏈(在導出 Heap Dump 之前要手動觸發(fā) GC 來保證),如果有,則說明存在內存泄漏,然后再去排查具體引用。

這時會拿到 GC Roots 到該對象的路徑,通過對象之間的引用,可以清楚的看出這個對象沒有被回收的原因,然后再去定位問題。如果上面對象此時本來應該是被 GC 掉的,簡單的辦法就是將其中的某處置為 null 或者 remove 掉,使其到 GC Root 無路徑可達,處于不可觸及狀態(tài),垃圾回收器就可以回收了。反之,一個存在 GC Root 的對象是不會被垃圾回收器回收掉的。

2.3.2 Leak Suspects

如何使用JVM內存分析工具MAT

Leak Suspects 可以自動分析并提示可能存在的內存泄漏,可以直接定位到 Class 及對應的行數。


如何使用JVM內存分析工具MAT

比如:這里問題一的描述,列出了一些比較大的實例。點擊 Details 可以看到細節(jié)信息,另外還可點擊 See stacktrace 查看具體的線程棧信息(可直接定位到具體某個類中的方法)。

如何使用JVM內存分析工具MAT

在 Details 詳情頁面 Shortest Paths To the Accumulation Point 表示 GC root 到內存消耗聚集點的最短路徑,如果某個內存消耗聚集點有路徑到達 GC root,則該內存消耗聚集點不會被當做垃圾被回收。

實戰(zhàn):在某項目中,其中幾個 Tomcat 響應特別慢,打開 Java VisualVM 觀察 Tomcat(pid xxx)-Visual GC 發(fā)現 Spaces-Old 升高,Graphs-GC Time 比較頻繁且持續(xù)時間長、有尖峰(重啟后過段時間又出現了),最后通過 Leak Suspects 中的 See stacktrace 定位到某個查詢接口,仔細排查代碼后發(fā)現有個 BUG:在特定查詢條件下會一次性查詢幾萬的數據出來(因為臟數據),處理過后恢復正常。

如何使用JVM內存分析工具MAT

2.3.3 內存快照對比

為了更有效率的找出內存泄露的對象,一般會獲取兩個堆轉儲文件(先 dump 一個,隔段時間再 dump 一個),通過對比后的結果可以很方便定位。

如何使用JVM內存分析工具MAT

如何使用JVM內存分析工具MAT

“如何使用JVM內存分析工具MAT”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

jvm
AI