当你从c&c++转到一门具有垃圾回收功能的语言时,程序员的工作就会变得更加容易,因为你用完对象,他们会被自动回收,但是,java程序员真的不需要考虑内存泄露吗? 其实不然

1.举个例子-看你能否找出内存泄漏

import java.util.Arrays;public class Stack {    private Object[] elements;    private int size = 0;    private static final int DEFAULT_INITIAL_CAPACITY = 16;    public Stack() {
        elements = new Object[DEFAULT_INITIAL_CAPACITY];
    }    public void push(Object e) {        ensureCapacity();
        elements[size++] = e;
    }    public Object pop() {        if (size == 0)            throw new EmptyStackException();        return elements[--size];
    }    private void ensureCapacity() {        if (elements.length == size)
            elements = Arrays.copyOf(elements, 2 * size + 1);
    }
}

1.1原因分析

上述程序并没有明显的错误,但是这段程序有一个内存泄漏,随着GC活动的增加,或者内存占用的不断增加,程序性能的降低就会表现出来,严重时可导致内存泄漏,但是这种失败情况相对较少。
代码的主要问题在pop函数,下面通过这张图示展现
假设这个栈一直增长,增长后如下图所示
iOS培训,Swift培训,苹果开发培训,移动开发培训
当进行大量的pop操作时,由于引用未进行置空,gc是不会释放的,如下图所示
iOS培训,Swift培训,苹果开发培训,移动开发培训

从上图中看以看出,如果栈先增长,在收缩,那么从栈中弹出的对象将不会被当作垃圾回收,即使程序不再使用栈中的这些队象,他们也不会回收,因为栈中仍然保存这对象的引用,俗称过期引用,这个内存泄露很隐蔽。

1.

网友评论