import java.util.Arrays;import java.util.EmptyStackException;public class Stack {private static final int DEFAULT_INITIAL_CAPACITY = 16; // 长度是16private Object[] elements;private int size = 0;public Stack() {//长度默认16elements = new Object[DEFAULT_INITIAL_CAPACITY];}//入栈public void push(Object e) {ensureCapacity(); // 扩容elements[size++] = e;}//出栈//存在内存泄漏public Object pop2() {if (size == 0)throw new EmptyStackException();// 这里存在内存泄露的问题//只是指针移动了, 但是数组原来的值还在,这就有问题了,原来的值已经不需要了,//但是还在数组里面,这样就无法被回收掉,就存在内存泄露了.// 解决办法就是将数组原来的值设置为null: elements[size] = null;return elements[--size];}//这个方法是针对pop2的内存泄露问题,做了一个解决优化public Object pop() {if (size == 0)throw new EmptyStackException();Object result = elements[--size];//优化点是将已经出栈的对象对应的数组下标位置的值设置为null,//这样置空了引用,下次GC触发的时候,就会清理掉这些已经出栈的对象elements[size] = null;return result;}//扩容private void ensureCapacity() {//数组的length和 数组里面实际的元素个数一样了,就需要扩容了.if (elements.length == size)//数组复制操作elements = Arrays.copyOf(elements, 2 * size + 1);}}
上面代码pop2方法会出现内存泄露问题,具体为什么内存泄露,看pop2方法注释,解决办法就是pop方法, pop方法就是pop2方法针对内存泄露的问题进行优化后的效果.
pop2方法存在的问题:
pop2方法由于引用没有进行置空,GC是不会释放的,就向下面的图所示,这就会出现内存泄露的问题
