JVM 內存分析工具 Memory Analyzer Tool(MAT)的深度講解

目錄

一. 前言

二.?MAT 使用場景及主要解決問題

三. MAT 基礎概念

3.1. Heap Dump

3.2.?Shallow Heap

3.3.?Retained Set

3.4.?Retained Heap

3.5.?Dominator Tree

3.6.?OQL

3.7.?references

四.?MAT 功能概述

4.1.?內存分布

4.2.?對象間依賴

4.3.?對象狀態

4.4.?按條件檢索對象

4.5.?常見內存分析工具對比

五.?Quick Start 及使用技巧

5.1. Quick Start

5.2.?使用技巧及注意事項


一. 前言

? ? Memory Analyzer Tool(簡稱:MAT),是一款快速便捷且功能強大豐富的 JVM 堆內存離線分析工具。其通過展現 JVM 異常時所記錄的運行時堆轉儲快照(Heap Dump)狀態(正常運行時也可以做堆轉儲分析),幫助定位內存泄漏問題或優化大內存消耗邏輯。

二.?MAT 使用場景及主要解決問題

場景一:內存溢出,JVM 堆區或方法區放不下存活及待申請的對象。如:高峰期系統出現 OOM(Out of Memory)異常,需定位內存瓶頸點來指導優化。

場景二:內存泄漏,不會再使用的對象無法被垃圾回收器回收。如:系統運行一段時間后出現 Full GC,甚至周期性 OOM 后需人工重啟解決。

場景三:內存占用高。如:系統頻繁 GC ,需定位影響服務實時性、穩定性、吞吐能力的原因。

三. MAT 基礎概念

3.1. Heap Dump

? ? Heap Dump 是 Java 進程堆內存在一個時間點的快照,支持 HPROF 及 DTFJ 格式,前者由 Oracle 系列 JVM 生成,后者是 IBM 系列 JVM 生成。其內容主要包含以下幾類:
1. 所有對象的實例信息:對象所屬類名、基礎類型和引用類型的屬性等。
2. 所有類信息:類加載器、類名、繼承關系、靜態屬性等。
3. GC Root:GC Root 代表通過可達性分析來判定 JVM 對象是否存活的起始集合。JVM 采用追蹤式垃圾回收(Tracing GC)模式,從所有 GC Roots 出發通過引用關系可以關聯的對象就是存活的(且不可回收),其余的不可達的對象(Unreachable object:如果無法從 GC Root 找到一條引用路徑能到達某對象,則該對象為Unreachable object)可以回收。
4. 線程棧及局部變量:快照生成時刻的所有線程的線程棧幀,以及每個線程棧的局部變量。

3.2.?Shallow Heap

? ? Shallow Heap 代表一個對象結構自身所占用的內存大小,不包括其屬性引用對象所占的內存。如 java.util.ArrayList 對象的 Shallow Heap 包含8字節的對象頭、8字節的對象數組屬性 elementData 引用 、 4字節的 size 屬性、4字節的 modCount 屬性(從 AbstractList 繼承及對象頭占用內存大小),有的對象可能需要加對齊填充但 ArrayList 自身已對齊不需補充,注意不包含 elementData 具體數據占用的內存大小。

3.3.?Retained Set

? ? 一個對象的 Retained Set,指的是該對象被 GC 回收后,所有能被回收的對象集合(如下圖所示,G 的 Retain Set 只有 G 并不包含 H,原因是雖然 H 也被 G 引用,但由于 H 也被 F 引用 ,G 被垃圾回收時無法釋放 H);另外,當該對象無法被 GC 回收,則其 Retained set 也必然無法被 GC 回收。

3.4.?Retained Heap

? ? Retained Heap 是一個對象被 GC 回收后,可釋放的內存大小,等于釋放對象的 Retained Heap 中所有對象的 Shallow Heap 的和(如下圖所示,E 的 Retain Heap 就是 G 與 E 的 Shallow Heap 總和,同理不包含 H)。

3.5.?Dominator Tree

? ? 如果所有指向對象 Y 的路徑都經過對象 X,則 X 支配(dominate) Y(如下圖中,C、D 均支配 F,但 G 并不支配 H)。Dominator tree 是根據對象引用及支配關系生成的整體樹狀圖,支配樹清晰描述了對象間的依賴關系,下圖左的 Dominator tree 如下圖右下方支配樹示意圖所示。支配關系還有如下關系:
1. Dominator tree 中任一節點的子樹就是被該節點支配的節點集合,也就是其 Retain Set。
2. 如果 X 直接支配 Y,則 X 的所有支配節點均支配 Y。

3.6.?OQL

? ? OQL 是類似于 SQL 的 MAT 專用統一查詢語言,可以根據復雜的查詢條件對 dump 文件中的類或者對象等數據進行查詢篩選。

3.7.?references

? ? outgoing references、incoming references 可以直擊對象間依賴關系,MAT 也提供了鏈式快速操作。
1. outgoing references:對象引用的外部對象(注意不包含對象的基本類型屬性。基本屬性內容可在 inspector 查看)。
2. incoming references:直接引用了當前對象的對象,每個對象的 incoming references 可能有 0 到多個。

四.?MAT 功能概述

? ? MAT 的產品能力非常豐富,工作原理是對 dump 文件建立多種索引,并基于索引來實現:1. 內存分布;2. 對象間依賴(如實體對象引用關系、線程引用關系、ClassLoader引用關系等);3. 對象狀態(內存占用量、字段屬性值等);4. 條件檢索(OQL、正則匹配查詢等)。這四大核心功能,并通過可視化展現輔助 Developer 精細化了解 JVM 堆內存全貌。

4.1.?內存分布

全局概覽信息:堆內存大小、對象個數、類的個數、類加載器的個數、GC root 個數、線程概況等全局統計信息。

Dominator tree:按對象的 Retain Heap 排序,也支持按多個維度聚類統計,最常用的功能之一。

Histogram:羅列每個類實例的內存占比,包括自身內存占用量(Shallow Heap)及支配對象的內存占用量(Retain Heap),支持按 package、class loader、super class、class 聚類統計,最常用的功能之一。

Leak Suspects:直擊引用鏈條上占用內存較多的可疑對象,可解決一些基礎問題,但復雜的問題往往幫助有限。

Top Consumers:展現哪些類、哪些 class loader、哪些 package 占用最高比例的內存。

4.2.?對象間依賴

References:提供對象的外部引用關系、被引用關系。通過任一對象的直接引用及間接引用詳情(主要是屬性值及內存占用),進而提供完善的依賴鏈路詳情。

Dominator tree:支持按對象的 Retain Heap 排序,并提供詳細的支配關系,結合 references 可以實現大對象快速關聯分析。

Thread overview:展現轉儲 dump 文件時線程棧幀等詳細狀態,也提供各線程的 Retain Heap 等關聯內存信息。

Path To GC Roots:提供任一對象到 GC Root 的鏈路詳情,幫助了解不能被 GC 回收的原因。

4.3.?對象狀態

最核心的是通過 inspector 面板提供對象的屬性信息、類繼承關系信息等數據,協助分析內存占用高與業務邏輯的關系。

集合狀態的檢測,如:通過 ArrayList 或數組的填充率定位空集合空數組造成的內存浪費、通過 HashMap 沖突率判定 hash 策略是否合理等。

4.4.?按條件檢索對象

OQL:提供一種類似于SQL的對象(類)級別統一結構化查詢語言。如:查找 size=0 且未使用過的 ArrayList: select * from java.util.ArrayList where size=0 and modCount=0;查找所有的String的 length 屬性的: select s.length from instanceof String s。

內存分布及對象間依賴的眾多功能,均支持按字符串檢索、按正則檢索等操作。

按虛擬內存地址尋址,根據對象的十六進制地址查找對象。

此外,為了便于記憶與回顧,整理了如下腦圖:

4.5.?常見內存分析工具對比

下圖中 Y 表示支持,N 表示不支持,時間截至發稿前。

產品功能MATJProfilerVisual VMjhatjmaphprof
對象關聯分析、深淺堆、GC ROOT、內存泄漏檢測、線程分析、提供自定義程序擴展擴展YNNNNN
離線全局分析YNYYNN
內存實時分配情況NYYYYY
OQLYNYNNN
內存分配堆棧、熱點比例NYNNNN
堆外內存分析NNNNNN

注 1:Dump 文件包含快照被轉儲時刻的 Java 對象在堆內存中的分布情況,但快照只是瞬間的記錄,所以不包含對象在何時、在哪個方法中被分配這類信息。

注 2:一般堆外內存溢出排查可結合 gperftools 與 btrace 排查,本文不展開介紹。

五.?Quick Start 及使用技巧

5.1. Quick Start

1. 安裝 MAT:【下載鏈接】;也可直接集成到 Eclipse IDE中(路徑:Eclipse → Help → Eclipse Marketplace → 搜 “MAT”)。

2. 調節 MAT 堆內存大小:MAT 分析時也作為 Java 進程運行,如果有足夠的內存,建議至少分配 dump 文件大小 * 1.2 倍的內存給 MAT,這樣分析速度會比較快。方式是修改 MemoryAnalyer.ini文件,調整 Xmx 參數(Windows 可用搜索神器 everything 軟件查找并修改、MAC OS 一般在 /Applications/mat.app/Contents/Eclipse/MemoryAnalyzer.ini,如找不到可用 Alfred 軟件查詢修改)。

3. 獲取堆快照 dump 文件(堆轉儲需要先執行 Full GC,線上服務使用時請注意影響),一般用三種方式:
1>. 使用 JDK 提供的 jmap 工具,命令是 jmap -dump:format=b,file=文件名 進程號。當進程接近僵死時,可以添加 -F 參數強制轉儲:jmap -F -dump:format=b,file=文件名 進程號。
2>. 本地運行的 Java 進程,直接在 MAT 使用 File → accquire heap dump 功能獲取。
3>. 啟動 Java 進程時配置JVM參數:-XX:-HeapDumpOnOutOfMemoryError,當發生 OOM 時無需人工干預會自動生成 dump文件。指定目錄用 -XX:HeapDumpPath=文件路徑來設置。

4. 分析 dump 文件:路徑是 File → Open Heap Dump ,然后 MAT 會建立索引并分析,dump 文件較大時耗時會很長。分析后 dump 文件所在目錄會有后綴為 index 的索引文件,也會有包含 HTML 格式的后綴為 zip 的文件。

5. 完成索引計算后,MAT 呈現概要視圖(Overview),包含三個部分:
1>. 全局概覽信息,堆內存大小、類數量、實例數量、Class Loader數量。
2>. Unreachable Object Histogram,展現轉儲快照時可被回收的對象信息(一般不需要關注,除非 GC 頻繁影響實時性的場景分析才用到)。
3>. Biggest Objects by Retained Size,展現經過統計過的哪幾個實例所關聯的對象占內存總和較高,以及具體占用的內存大小,一般相關代碼比較簡單情況下,往往可以直接分析具體的引用關系異常,如內存泄漏等。此外也包含了最大對象和鏈接支持繼續深入分析。

6. 如果代碼比較復雜,需要繼續使用 MAT 各種工具并結合業務代碼進一步分析內存異常的原因。最常用的幾項如下:?
1>. 查看堆整體情況的:Histogram、Dominator tree、Thread details等(各功能入口整理如下)

2>.?MAT 分析過的 Top Consumers 、Leak Suspects 等

5.2.?使用技巧及注意事項

1. 注意對運行進程的性能影響:Heap Dump 時會先進行 Full GC,另外為保證對象數據視圖一致,需要在安全點 Stop The World 暫停響應,線上服務進行務必注意性能影響。可以采取以下技巧減少影響:
1>. 先禁用入口流量,再執行 dump 動作。
2>. 選擇影響較小時 dump 內存。
3>. 使用腳本捕獲指定事件時 dump 內存。

2. Dump 文件及建立的索引文件可能較大,如果開發機配置不足無法分析,可在服務器先執行分析后,基于分析后的索引文件直接查看結果,另外也需要注意磁盤占用問題:
1>. 大文件分析方法:一般 dump 文件不高于分析機主存 1.2 倍可直接在開發機分析;若 dump 文件過大,可以使用 MAT 提供的腳本在配置高的高配機器先建立索引再直接展現索引分析結果(一般是 Linux 機器,可以使用 MAT 提供的腳本:./ParseHeapDump.sh $HEAPDUMP,堆信息有 unreachable 標記的垃圾對象,在 dump 時也保存了下來,默認不分析此部分數據,如需要在啟動腳本 ParseHeapDump.sh 中加入:-keep_unreachable_objects)。
2>. 如果不關注堆中不可達對象,使用“live”參數可以減小文件大小,命令是 jmap -dump:live,format=b,file=
3>. Dump 前主動手動執行一次 FULL GC ,去除無效對象進一步減少 dump 堆轉儲及建立索引的時間。
4>. Dump文件巨大,建立索引后發現主視圖中對象占用內存均較小,這是因為絕大部分對象未被 GC Roots 引用可釋放。
5>. Dump 時注意指定到空間較大的磁盤位置,避免打滿分區影響服務。
6>. 建立 dump 索引機器的磁盤空間需要足夠大,一般至少是 dump 文件的兩倍,因為生成的中間索引文件也較大,如下圖:

3. 其他

1>. JDK 版本問題:如遇“VMVersionMismatchException”,使用啟動目標進程的 JDK 版本即可。
2>. 部分核心功能主界面未展現,問題足夠復雜時需打開,如 MAT 默認不打開 inspector,如需根據對象數據值做業務分析,建議打開該視圖。
3>. 配置了 HeapDumpOnOutOfMemoryError 參數,但 OutOfMemoryError 時但沒有自動生成 dump 文件,可能原因有三個:
?? ?3.1>. 應用程序自行創建并拋出 OutOfMemoryError;
?? ?3.2>. 進程的其他資源(如線程)已用盡;
?? ?3.3>. C 代碼(如 JVM 源碼)中堆耗盡,這種可能由于不同的原因而出現,例如在交換空間不足的情況下,進程限制用盡或僅地址空間的限制,此時 dump 文件分析并無實質性幫助。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/212692.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/212692.shtml
英文地址,請注明出處:http://en.pswp.cn/news/212692.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

鴻蒙前端開發-構建第一個ArkTS應用(Stage模型)

創建ArkTS工程 若首次打開DevEco Studio,請點擊Create Project創建工程。如果已經打開了一個工程,請在菜單欄選擇File > New > Create Project來創建一個新工程。 選擇Application應用開發(本文以應用開發為例,Atomic Serv…

docker-compose安裝教程

1.確認docker-compose是否安裝 docker-compose -v如上圖所示表示未安裝,需要安裝。 如上圖所示表示已經安裝,不需要再安裝,如果覺得版本低想升級,也可以繼續安裝。 2.離線安裝 下載docker-compose安裝包,上傳到服務…

uniapp小程序分享為灰色

引用:https://www.cnblogs.com/panwudi/p/17074172.html uniapp開發的微信小程序,沒有轉發,分享: 創建一個mixin:common/share.js export default {onShareAppMessage(res) { //發送給朋友return {}},onShareTimeline(res) {//…

人工智能原理復習--機器學習

文章目錄 上一篇機器學習概述歸納(示例)學習ID3決策樹算法K近鄰算法下一篇 上一篇 人工智能原理復習–搜索策略(二) 機器學習概述 學習系統的基本結構: #mermaid-svg-JMjIZHjVOirLolvu {font-family:"trebuchet ms",verdana,ari…

辨析旅行商問題(TSP)與車輛路徑問題(VRP)

目錄 前言旅行商問題 (TSP)問題介紹數學模型符號定義問題輸入約束條件目標函數問題輸出 解的空間解空間大小計算解釋 車輛路徑問題 (VRP)問題介紹TSP到VRP的過渡數學模型符號定義問題輸入約束條件優化目標問題輸出 解空間特殊情況一般情況 TSP 與 VRP 對比 前言 計劃是通過本文…

基于JavaWeb+SSM+Vue助農扶貧微信小程序系統的設計和實現

基于JavaWebSSMVue助農扶貧微信小程序系統的設計和實現 源碼獲取入口Lun文目錄前言主要技術系統設計功能截圖 源碼獲取入口 Lun文目錄 目 錄 第一章 緒論 1 1.1 研究背景 1 1.2 研究意義 1 1.3 研究內容 2 第二章 開發環境與技術 3 2.1 JSP技術 3 2.2 MySQL數據庫 3 2.3 Java…

基于Solr的全文檢索系統的實現與應用

文章目錄 一、概念1、什么是Solr2、與Lucene的比較區別1)Lucene2)Solr 二、Solr的安裝與配置1、Solr的下載2、Solr的文件夾結構3、運行環境4、Solr整合tomcat1)Solr Home與SolrCore2)整合步驟 5、Solr管理后臺1)Dashbo…

4-Docker命令之docker commit

1.docker commit介紹 docker commit命令是用于根據docker容器的改變創建一個新的docker鏡像 2.docker commit用法 docker commit [參數] container [repository[:tag]] [rootcentos79 ~]# docker commit --helpUsage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG…

微服務學習:Nacos配置中心

先打開Nacos(詳見微服務學習:Nacos微服務架構中的服務注冊、服務發現和動態配置&Nacos下載) 1.環境隔離: 新建命名空間: 記住命名空間ID: c82496fb-237f-47f7-91ed-288a53a63324 再配置 就可達成環…

vue3 創建過程中 運行npm create vue@latest 和 npm install卡住不動的解決方法之一

問題:npm create vuelatest、和npm install 不管是電腦cmd上還是vscode終端上都是卡很久或不動! 解決: 1、查看npm代理 npm config get registry2、更換npm鏡像 npm config set registryhttps://registry.npmmirror.com這里換成淘寶源好像…

學習 Vue 3 源碼

Vue 3 是一款流行的前端框架,它的數據代理和虛擬 DOM 實現是其核心功能之一 Vue 3 的數據代理 在 Vue 3 中,數據代理是指將組件實例的屬性代理到其內部狀態對象上。這使得開發者可以使用更便捷的方式來訪問和修改組件的狀態。 Vue 3 的數據代理實現主…

docker-centos中基于keepalived+niginx模擬主從熱備完整過程

文章目錄 一、環境準備二、主機1、環境搭建1.1 鏡像拉取1.2 創建網橋1.3 啟動容器1.4 配置鏡像源1.5 下載工具包1.6 下載keepalived1.7 下載nginx 2、配置2.1 配置keepalived2.2 配置nginx2.2.1 查看nginx.conf2.2.2 修改index.html 3、啟動3.1 啟動nginx3.2 啟動keepalived 4、…

【HarmonyOS開發】控件開發過程中,知識點記錄

1、問題記錄及解決方案 1.1 資源(Icon&i18n)問題 控件:只有一個JS文件,不會將任何資源型文件(圖片、字體、默認文字等)打包到SO中。因此,當我們開發控件時,需要將需要使用到的資…

【機器學習】042_遷移學習

一、概述、定義 目的: 遷移學習的目的是將某個領域或任務上學習到的模式、知識應用到不同但相關的領域里,獲取更多數據,而不必投入許多時間人力來進行數據的標注。 舉例: 已經會下中國象棋,就可以類比著來學習國際…

Java單元測試:JUnit和Mockito的使用指南

引言: 在軟件開發過程中,單元測試是一項非常重要的工作。通過單元測試,我們可以驗證代碼的正確性、穩定性和可維護性,幫助我們提高代碼質量和開發效率。本文將介紹Java中兩個常用的單元測試框架:JUnit和Mockito&#x…

Navicat連接Oracle數據庫

Navicat連接Oracle數據庫 打開服務里面找到Oracle服務 OracleServerXE或者OracleServerTTL 創建數據庫連接 連接名默認自己起 主機選擇本地 端口默認 服務名在服務中可以找到輸入后綴 用戶名默認都是system 密碼是創建oracle時候填寫的口令 點擊測試連接即可

Spring Boot中的事務是如何實現的?懂嗎?

SpringBoot中的事務管理,用得好,能確保數據的一致性和完整性;用得不好,可能會給性能帶來不小的影響哦。 基本使用 在SpringBoot中,事務的使用非常簡潔。首先,得感謝Spring框架提供的Transactional注解&am…

【金融數據分析】計算滬深300指數行業權重分布并用餅圖展示

前言 前面的文章我們已經介紹了如何獲取滬深300成分股所述行業以及權重的數據,想要了解這部分內容的小伙伴可以閱讀上一篇文章 springbootjdbcTemplatesqlite編程示例——以滬深300成分股數據處理為例-CSDN博客 那么有了上文獲取的數據,我們實際上可以…

【rabbitMQ】rabbitMQ控制臺模擬收發消息

目錄 1.新建隊列 2.交換機綁定隊列 3.查看消息是否到達隊列 總結: 1.新建隊列 2.交換機綁定隊列 點擊amq.fonout 3.查看消息是否到達隊列 總結: 生產者(publisher)發送消息,先到達交換機,再到隊列&…

微信小程序uni-app:常用Form表單組件使用示例

目錄 input 輸入框picker 選擇器 input 輸入框 https://developers.weixin.qq.com/miniprogram/dev/component/input.htmlhttps://uniapp.dcloud.net.cn/component/input.html <inputclass"input-class"type"text"v-model"value"placeholde…