import java.util.Arrays;
import java.util.EmptyStackException;
public class Stack {
private static final int DEFAULT_INITIAL_CAPACITY = 16; // 长度是16
private Object[] elements;
private int size = 0;
public Stack() {
//长度默认16
elements = 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是不会释放的,就向下面的图所示,这就会出现内存泄露的问题