声明:这是转载的。
测试类:
Element.java
package com.memoryleak.demo;
public class Element {
private byte[] data;
public Element(int size){
this.data = new byte[size];
}
}
LeakStack.java
package com.memoryleak.demo;
import java.util.EmptyStackException;
/**
* Demo: 存在内存泄露的堆栈
*
*/
public class LeakStack {
private Object[] stack;
private int top = -1;
public LeakStack(int initialCapicity){
stack = new Object[initialCapicity];
}
public void push(Object e){
ensureCapacity();
top++;
stack[top] = e;
}
public Object pop(){
if(top == -1)
throw new EmptyStackException();
Object temp = stack[top];
// stack[top] = null;
top--;
return temp;
}
/**
* 判断是否栈满,如果栈满则自动扩充
*/
public void ensureCapacity(){
if(stack.length == top + 1){
Object[] temp = stack;
stack = new Object[2 * stack.length + 1];
System.arraycopy(temp, 0, stack, 0, top);
}
}
}
测试主方法类:
package com.memoryleak.demo;
import java.util.EmptyStackException;
public class AppTest {
public static void main(String[] args) {
try{
int round = 1000;
LeakStack s = new LeakStack(2000);
for(int i=0; i<2; i++){
System.out.println("push " + i);
for(int j=0; j<round; j++){
s.push(new Element(65000));
}
System.out.println("pop " + i);
for(int m=0; m<round; m++)
s.pop();
}
}catch (EmptyStackException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
使用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内存泄漏问题的一次实战
这篇文章介绍的不错,可以参考