Java内存泄露测试及工具

声明:这是转载的。

测试类:

Element.java

[java] view plaincopy
  1. package com.memoryleak.demo;  
  2.   
  3. public class Element {  
  4.     private byte[] data;  
  5.       
  6.     public Element(int size){  
  7.         this.data = new byte[size];  
  8.     }  
  9.   
  10. }  

LeakStack.java

[java] view plaincopy
  1. package com.memoryleak.demo;  
  2.   
  3. import java.util.EmptyStackException;  
  4.   
  5. /** 
  6.  * Demo: 存在内存泄露的堆栈 
  7.  * 
  8.  */  
  9.   
  10. public class LeakStack {  
  11.     private Object[] stack;  
  12.     private int top = -1;  
  13.       
  14.     public LeakStack(int initialCapicity){  
  15.         stack = new Object[initialCapicity];  
  16.     }  
  17.       
  18.     public void push(Object e){  
  19.         ensureCapacity();  
  20.         top++;  
  21.         stack[top] = e;  
  22.     }  
  23.       
  24.     public Object pop(){  
  25.         if(top == -1)  
  26.             throw new EmptyStackException();  
  27.         Object temp = stack[top];  
  28. //      stack[top] = null;  
  29.         top--;  
  30.         return temp;  
  31.     }  
  32.       
  33.     /** 
  34.      * 判断是否栈满,如果栈满则自动扩充 
  35.      */  
  36.     public void ensureCapacity(){  
  37.         if(stack.length == top + 1){  
  38.             Object[] temp = stack;  
  39.             stack = new Object[2 * stack.length + 1];  
  40.             System.arraycopy(temp, 0, stack, 0, top);  
  41.         }  
  42.     }  
  43. }  

测试主方法类:

[java] view plaincopy
  1. package com.memoryleak.demo;  
  2.   
  3. import java.util.EmptyStackException;  
  4.   
  5. public class AppTest {  
  6.     public static void main(String[] args) {  
  7.         try{  
  8.             int round = 1000;  
  9.             LeakStack s = new LeakStack(2000);  
  10.               
  11.             for(int i=0; i<2; i++){  
  12.                 System.out.println("push " + i);  
  13.                 for(int j=0; j<round; j++){  
  14.                     s.push(new Element(65000));  
  15.                 }  
  16.                   
  17.                 System.out.println("pop " + i);  
  18.                 for(int m=0; m<round; m++)  
  19.                     s.pop();  
  20.             }  
  21.         }catch (EmptyStackException e) {  
  22.             // TODO: handle exception  
  23.             e.printStackTrace();  
  24.         }  
  25.     }  
  26.   
  27. }  

使用jdk自带工具hprof

用JVM的-Xrunhprof选项可以打开hprof工具

java -Xrunhprof:heap=sites,file=log.txt com.memoryleak.demo.AppTest

Eclipse中的参数配置



打开log.txt文件


live表示活跃的,allocate表示已分配的;

从上往下占用内存降序排列,排在第一位的占用内存最多,为130032000byte 约130m,占内存总量的99.75%

objs 表示对象的个数

从图上看活跃的1032个对象,总共分配了2000个对象。在这里如果发生内存泄露 OutOfMemoryError时

活跃数就和分配数相差无几。


可根据末尾的trace name 找到更详细的trace说明,作进一步的判断



排第一的300209,可以找到相关的类是Element,也就是说Element对象没有得到及时的回收。


有一个被广泛使用的工具是JRockit,现在貌似是免费的了

http://hi.baidu.com/shiliangshuai/item/852d5b3546e735d56c15e95a

使用JRockit作为工具检测并解决JAVA内存泄漏问题的一次实战

这篇文章介绍的不错,可以参考


posted on 2013-12-17 20:22  Java码界探秘  阅读(142)  评论(0编辑  收藏  举报

导航