內存分析工具MAT


首先介紹一下MAT的安裝

下載地址:https://eclipse.org/mat/downloads.php

選擇自己系統相應的版本下載,下載完得到一個zip文件,解壓后雙擊EXE文件就可以直接使用了

 

使用jmap得到的.hprof 文件,使用MAT工具打開進行進一步的分析,選擇第一個Leak Suspects Report

 

Histogram 可以列出內存中的對象,對象的個數以及大小,需要重點關注

它按類名將所有的實例對象列出來,點擊表頭(Class Name)可以排序,第一行輸入正則表達式可以過濾篩選 ;

Shallow Heap :一個對象內存的消耗大小,不包含對其他對象的引用;
Retained Heap :是shallow Heap的總和,也就是該對象被GC之后所能回收的內存大小;

 

 

 

在某一項上右鍵打開菜單選擇 list objects :

with incoming references 將列出哪些類引入該類;

with outgoing references 列出該類引用了哪些類

 

 Dominator Tree可以列出那個線程,以及線程下面的那些對象占用的空間

可以列出內存中存活的大對象列表,優點是有Percentage字段,可以看各種情況的百分比。

分組工具可以根據自己的需求分組查找,默認根據class分組,本文中是根據 package分組,建議按package進行分組,可以清楚的跟進自己寫的包的情況

快速找出某個實例沒被釋放的原因,可以右健 Path to GC Roots-->exclude all phantom/weak/soft etc. references

它展示了對象間的引用關系,比如SSLSocketImpl @0xa124b208被PushNotificationManager 實例中的socket屬性所引用。

 

Top consumers通過圖形列出最大的object

多種維度(包括 類大小、類加載器、包名)展示占用內存比較多的對象的分布,從而定位內存資源主要耗費在哪些地方!

 

Leak Suspects通過MA自動分析泄漏的原因,需要重點關注

 

 

Java 的內存泄漏問題比較難以定位,下面針對一些常見的內存泄漏場景做介紹:

  1. 持續在堆上創建對象而不釋放。例如,持續不斷的往一個列表中添加對象,而不對列表清空。這種問題,通常可以給程序運行時添加 JVM 參數-Xmx 指定一個較小的運行堆大小,這樣可以比較容易的發現這類問題。
  2. 不正確的使用靜態對象。因為 static 關鍵字修飾的對象的生命周期與 Java 程序的運行周期是一致的,所以垃圾回收機制無法回收靜態變量引用的對象。所以,發生內存泄漏問題時,我們要着重分析所有的靜態變量。
  3. 對大 String 對象調用 String.intern()方法,該方法會從字符串常量池中查詢當前字符串是否存在,若不存在就會將當前字符串放入常量池中。而在 jdk6 之前,字符串常量存儲在 PermGen 區的,但是默認情況下 PermGen 區比較小,所以較大的字符串調用此方法,很容易會觸發內存溢出問題。
  4. 打開的輸入流、連接沒有爭取關閉。由於這些資源需要對應的內存維護狀態,因此不關閉會導致這些內存無法釋放。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM