1. 程式人生 > >使用Eclipse Memory Analyzer進行記憶體洩漏分析三部曲

使用Eclipse Memory Analyzer進行記憶體洩漏分析三部曲

  • 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.輸入類名(輸入類的全名)