使用MAT(Memory Analyzer Tool)分析內存泄漏
在工作中,有時會遇到OutOfMemoryError,我們知道遇到Error一般表明程序存在著嚴重問題,可能是災難性的。所以找出是什么原因造成OutOfMemoryError非常重要。Memory Analyzer tool(MAT)來化解我們遇到的難題。
從可用內存和請求數量的變化情況判斷是突發性的內存泄露還是不斷積累的結果換句話說,首先定位內存泄露的性質:
突發內存泄露:
- 表現:可用內存直線下降,短時間內消耗殆盡。
- 原因:定時任務執行、用戶集中訪問等,頻繁調用有內存泄露的代碼塊。
- 排查:這種情況相對比較容易定位問題,查看可用內存驟降的時間點,從日志中查找對應時間點系統的行為(前提是日志必須很規范,有據可循)。 </ul>
- 表現:可用內存持續下降,隨著系統運行不斷減少。
- 原因:偶發性調用到有內存泄露的代碼塊。
- 排查:這種情況需要借助dump文件和內存分析工具來排查。常用方式:在系統啟動后獲取dump文件,運行一段時間后(可用內存明顯減少),再次 獲取dump文件(如果觸發了JVM的OOM,可以直接拿到dump),對比前后兩個時間點的內存占用情況,找出占用內存大幅增長的類。如果足夠明顯,可 以直接從自動生成的dump文件中發現占用內存過多的類。 </ul>
- Shortest Paths To the Accumulation Point
- Accumulated Objects in Dominator Tree
- Accumulated Objects by Class in Dominator Tree
- All Accumulated Objects by Class </ul>
隱式內存泄露:
分析不同服務器的內存使用情況可以進一步縮小排查范圍
使用jmap工具生成dump文件
jmap是什么?簡單來說,jmap是JDK自帶的一種用于生成內存鏡像文件的工具,通過該工具,開發人員可以快速生成dump文件。
進入目錄:/usr/java/jdk1.6.0_33/bin
找到服務的進程ID:ps –ef | grep search
執行命令:jmap -dump:format=b,file=<path<PID>
下載dump文件至本地
</blockquote>MAT工具的下載和安裝
MemoryAnalyzer.ini 可以設置最大/最小堆內存,與eclipse.ini配置類似
使用MAT工具進行內存泄露分析
當成功啟動MAT后,通過菜單選項“File->Open heap dump...”打開指定的dump文件后,將會生成Overview選項,在概況中可以初步查看占用內存最多的幾個類以及對應的一些屬性、引用層次和統計信息
![]()
在Overview選項中,以餅狀圖的形式列舉出了程序內存消耗的一些基本信息,其中每一種不同顏色的餅塊都代表了不同比例的內存消耗情況。如果說 需要定位內存泄露的代碼點,我們可以通過Dominator Tree菜單選項來進行排查(MAT工具僅僅只是一個輔助,分析OutofMemory并不存在一個固定的方式和準則,因此仔細觀察和分析才能夠找到問題 所在)
![]()
Histogram圖表中主要統計了消耗占比較高的類的實例數量及占用空間,Shallow Size: 對象自身占用的內存大小,不包括它引用的對象Retained Size: 當前對象大小 + 當前對象直接或間接引用的對象大小的總和 - 被GC Roots直接或間接引用的對象大小的總和
![]()
Top Consumers圖表可以更直觀地看到內存消耗占比最多的類,由于很多類都囊括在ClassLoader中,因此還需要進一步查看引用的層級。如果一次觀察的結果不夠明顯,可以對比不同服務器(不同組)、不同時間點的內存使用情況,進一步縮小排查范圍。
![]()
List objects with outgoing/incoming references 根據引用層級查看問題根源
![]()
Leak suspects,MAT可以自動生成可疑泄露點的報告,能夠從以下幾點全面分析問題:
</div> 作者:Hunng,Java空城獅,重慶人,重慶郵電大學 /碼字小學徒/
![]()
來自: http://hunng.com/2015/07/08/memory-analyzer-tool/