内存泄漏以及jmap命令的用法

查看内存泄漏命令:

命令 作用
jps 查看java进程号
jmap -histo:live 进程号 > 存放路径 将进程打印到文本中
start 路径名 打开文本,查看实例个数

过程如下:

这是用到的代码(也就是我放到TestDemo1.java中的代码):

/**
 * 栈
 */
class MyStack {
    private V[] elem;
    private int top;

    public MyStack() {
        this(10);
    }

    public MyStack(int size) {
        this.elem = new V[size];
        this.top = 0;
    }

    /**
     * 判空
     * @return
     */
    public boolean isEmpty() {
        return top == 0;
    }

    /**
     * 判满
     * @return
     */
    public boolean isFull() {
        return top == elem.length;
    }

    /**
     * 入栈
     * @param val
     */
    public void push(V val) {
        if(isFull()) {
            return ;
        }
        this.elem[this.top++] = val;
    }

    /**
     * 出栈
     */
    public void pop() {
        if(isEmpty()) {
            return ;
        }
        this.elem[top-1] = null; //这句是重点
        --this.top;
    }

    /**
     * 得到栈顶元素
     * @return
     */
    public V getTop() {
        if(isEmpty()) {
            return null;
        }
        return this.elem[this.top-1];
    }
}

/**
 * 自定义的一个类,一会将他的实例对象入栈
 */
class V {

}

public class TestDemo1 {
    public static void main(String[] args) throws InterruptedException {
        MyStack stack = new MyStack();
        stack.push(new V());
        stack.push(new V());
        stack.push(new V());
        //这里有3个V的对象
        stack.pop();   //出栈了一个
        System.gc();  //拿gc()去回收它
        Thread.sleep(100000);  //当前线程休眠100s
    }
}


我们现将栈类中出栈方法中的 this.elem[top-1] = null;屏蔽掉,然后编译运行:

shift+鼠标右键,打开一个powershell窗口:
内存泄漏以及jmap命令的用法_第1张图片

内存泄漏以及jmap命令的用法_第2张图片
这里我主线程只休眠了100s,所以接下来就要快点了:

还有要记得创建一个文本来接收,我这里用的是jmap.txt,那么编译之后是这样:
内存泄漏以及jmap命令的用法_第3张图片
打开另一个powershell窗口:
内存泄漏以及jmap命令的用法_第4张图片

得到的文本如下:
内存泄漏以及jmap命令的用法_第5张图片

可以看到,我出栈之后拿gc()去回收V的对象,但它还是有3个对象,这是因为我栈指针top下移了,但那个对象的引用还在,所以垃圾回收器并没有回收它,这就是内存泄漏,

怎么避免它呢,就是我们在不使用一个对象的时候把它置为空,让它没有引用去引用它,那么垃圾回收器就会回收它了,

现在我们出栈的时候将该对象的引用置为空,也就是放开栈类中出栈方法中的 this.elem[top-1] = null;现在,重新编译一次,运行:

然后在打开的另一个powershell窗口中再一次输入jmap命令:
内存泄漏以及jmap命令的用法_第6张图片

这时我们得到的文本如下:
内存泄漏以及jmap命令的用法_第7张图片

可以看到,实例对象已经只有两个了。

你可能感兴趣的:(java基础,java内存泄漏,jmap命令用法详解)