使用Eclipse Memory Analyzer進行內存泄漏分析三部曲

源地址:http://seanhe.iteye.com/blog/898277


一、準備工作 
分析較大的dump文件(根據我自己的經驗2G以上的dump文件就需要使用以下介紹的方法,不然mat會出現oom)需要調整虛擬機參數 
找個64位的系統在MemoryAnalyzer.ini設置-Xmx2g 
如果是32位的xp可以使用下面的方法進行嘗試:

安裝jrockit 6.0的JDK mat使用jrockit的jdk來啓動
Java代碼  收藏代碼
  1. -vm  
  2. D:/Program Files/Java/jrockit-R28.0.0-jre1.6.0_17/bin/jrockit/jvm.dll  
  3. -vmargs  
  4. -Xmx1700m  


二、開始使用MAT進行OOM分析 
第一步,啓動mat ,選擇File->Open Heap Dump 選擇你的dump文件。下面開始等待,mat解析dump文件需要花一些時間,在解析的同時會在硬盤上寫入一些解析結果文件,這樣下次打開時速度會快很多。有時候mat在解析過程中可能會出現出錯的情況,這個時候可以將那些臨時文件刪除以後重試第一步,如果你的rp夠好的話重試也許會解析成功。 

第二步,查看內存泄漏分析報表。mat解析完成以後會出現如下圖的提示: 
 
因爲我們就是爲了查找內存泄漏的問題,所以保持默認選項直接點“Finish”就可以。 
Mat會非常直觀的展現內存泄漏的可疑點,類似下面的報表可以直接看到某個線程佔用了大量的內存 

問題的詳細分析信息: 


第三步,開始尋找導致內存泄漏的代碼點。這時往往需要打開對象依賴關係樹形視圖,點擊如圖按鈕即可。 
 
這時會看到如下視圖 

這個視圖的左邊大區域可以看到對象的依賴關係,選中某個對象以後可以在左邊小窗口查看對象的一些屬性。如果屬性的值是一些內存地址你還可以點擊工具欄的搜索按鈕來搜索具體的對象信息。在進行具體分析的時候MAT只是起了幫助你進行分析的工具的功能,OOM問題分析沒有固定方法和準則。只能發揮你敏銳的洞察力,結合源代碼,對內存中的對象進行分析從而找到代碼中的BUG. 

使用貼士: 
關於shallow size、retained size(摘自http://www.360doc.com/content/11/0830/16/4520139_144514377.shtml) 
Shallow size就是對象本身佔用內存的大小,不包含對其他對象的引用,也就是對象頭加成員變量(不是成員變量的值)的總和。在32位系統上,對象頭佔用8字節,int佔用4字節,不管成員變量(對象或數組)是否引用了其他對象(實例)或者賦值爲null它始終佔用4字節。故此,對於String對象實例來說,它有三個int成員(3*4=12字節)、一個char[]成員(1*4=4字節)以及一個對象頭(8字節),總共3*4 +1*4+8=24字節。根據這一原則,對String a=”rosen jiang”來說,實例a的shallow size也是24字節 

Retained size是該對象自己的shallow size,加上從該對象能直接或間接訪問到對象的shallow size之和。換句話說,retained size是該對象被GC之後所能回收到內存的總和。爲了更好的理解retained size,不妨看個例子。 

把內存中的對象看成下圖中的節點,並且對象和對象之間互相引用。這裏有一個特殊的節點GC Roots,正解!這就是reference chain的起點。 
 
從obj1入手,上圖中藍色節點代表僅僅只有通過obj1才能直接或間接訪問的對象。因爲可以通過GC Roots訪問,所以左圖的obj3不是藍色節點;而在右圖卻是藍色,因爲它已經被包含在retained集合內。 
所以對於左圖,obj1的retained size是obj1、obj2、obj4的shallow size總和;右圖的retained size是obj1、obj2、obj3、obj4的shallow size總和。obj2的retained size可以通過相同的方式計算。 

如何查看某一個對象佔用的內存空間 
1.按以下方式打開新窗口即可 

2.輸入類名(輸入類的全名) 
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章