咱们看例子
public class Stack { private Object[] objects; private int size; private int STACK_LEN = 16; public Stack(){ objects = new Object[STACK_LEN]; } public void push(Object object){ ensureCapacity(); objects[size++] = object; } public Object pop(){ if(size == 0){ throw new EmptyStackException(); } return objects[--size]; } public void ensureCapacity(){ if(objects.length == size){ objects = Arrays.copyOf(objects,2*size+1); } } }
再来看一下调用地方
public static void main(String[] args){ Stack stack = new Stack(); for(int i = 0;i<20;i++){ stack.push(new Object()); } for(int i = 0;i<20;i++){ stack.pop(); } }
大家有没有发现,上述的stack中会出现内存泄漏呢?内存泄漏很隐蔽,在上述代码中确实不好找出来,因为在调用的时候,我们可以很明显看到,在main方法执行过程中,执行完成后,不会有什么异常出现,很正常的一个程序,在stack对象push然后再pop后,其中的Object 数组中的对象被一个个的pop出去,对于stack而已已经是一个个废弃对象了,不需要再使用到,但是数组还保持着对他的引用,无法被回收,这时应将这些pop出去的对象进行置空,让其真正被“废弃”
修改代码如下
public Object pop(){ if(size == 0){ throw new EmptyStackException(); } Object res = objects[--size]; objects[size] =null; return res; }
参考书籍《Effective Java》