Eclipse Memory Analyzer 分析內存泄露

OutOfMemoryError示例

代碼

package com.walson.heap;

import java.util.ArrayList;
import java.util.List;


/**
 * java 堆溢出
 *
 * -verbose:gc -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
 * @author gjh1
 *
 */
public class HeapOOM {

    static class OOMObject{
        
    }
    
    public static void main(String[] args) {
        List<OOMObject> list = new ArrayList<HeapOOM.OOMObject>();
        
        while (true) {
            list.add(new OOMObject());
            
        }
    }

}

php

java虛擬機設置

 

說明:java

  1. -Xms:最小堆內存
  2. -Xmx:最大堆內存
  3. 設置-Xms與-Xmx同樣都爲20M是爲了不堆內存知道擴展
  4. -XX:+HeapDumpOnOutOfMemoryError :虛擬機出現內存溢出異常時Dump出當前的內存堆轉儲快照以便過後分析。(項目文件夾下)

運行結果

[GC (Allocation Failure) 5504K->3237K(19840K), 0.0108051 secs]
[GC (Allocation Failure) 8741K->7223K(19840K), 0.0123580 secs]
[GC (Allocation Failure) 12727K->12727K(19840K), 0.0179589 secs]
[Full GC (Allocation Failure) 18231K->12016K(19840K), 0.0451467 secs]
[Full GC (Allocation Failure) 14714K->14711K(19840K), 0.0540938 secs]
[Full GC (Allocation Failure) 14711K->14691K(19840K), 0.0588749 secs]
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid4352.hprof ...
Heap dump file created [26506297 bytes in 0.267 secs]
 

說明:回收前Heap堆佔用大小-->回收後佔用大小(堆空間大小)最後是耗時多久(秒)數組

 

分析內存泄露

Memory Analyzer插件的安裝

首先,打開eclipse->Help->Install new software->work with右邊的Add...eclipse

彈出的對話框以下spa

在Name框中輸入名稱,location中輸入以下地址:插件

 http://download.eclipse.org/mat/1.2/update-site/
對象

這個地址安裝的版本是1.2.1。ip

具體版本下載地址爲http://www.eclipse.org/mat/downloads.php內存

點擊肯定就好。get


肯定了以後,出現了選擇安裝的界面。選擇所有便可。進行下一步一路next下去便可。

 

分析dump文件

打開堆內存轉儲文件

餅圖分析

 

從餅圖能夠看出整個heap14.3M,深色區域佔了13.9M,佔94.71%,懷疑深色區域爲內存泄露對象。下面描述The memory is accumulated in one instance of "java.lang.Object[]" loaded by "<system class loader>".大概是說深色區域的內存系統類加載器用來累積加載Object數組

詳細分析

 

Dominator Tree爲對象關係樹形圖

Shallow Heap與Retained Heap的計算

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是obj一、obj二、obj4的shallow size總和;右圖的retained size是obj一、obj二、obj三、obj4的shallow size總和。obj2的retained size能夠經過相同的方式計算。

 

找出內存泄露代碼

相關文章
相關標籤/搜索