1. import java.util.Arrays;
    2. import java.util.EmptyStackException;
    3. public class Stack {
    4. private static final int DEFAULT_INITIAL_CAPACITY = 16; // 长度是16
    5. private Object[] elements;
    6. private int size = 0;
    7. public Stack() {
    8. //长度默认16
    9. elements = new Object[DEFAULT_INITIAL_CAPACITY];
    10. }
    11. //入栈
    12. public void push(Object e) {
    13. ensureCapacity(); // 扩容
    14. elements[size++] = e;
    15. }
    16. //出栈
    17. //存在内存泄漏
    18. public Object pop2() {
    19. if (size == 0)
    20. throw new EmptyStackException();
    21. // 这里存在内存泄露的问题
    22. //只是指针移动了, 但是数组原来的值还在,这就有问题了,原来的值已经不需要了,
    23. //但是还在数组里面,这样就无法被回收掉,就存在内存泄露了.
    24. // 解决办法就是将数组原来的值设置为null: elements[size] = null;
    25. return elements[--size];
    26. }
    27. //这个方法是针对pop2的内存泄露问题,做了一个解决优化
    28. public Object pop() {
    29. if (size == 0)
    30. throw new EmptyStackException();
    31. Object result = elements[--size];
    32. //优化点是将已经出栈的对象对应的数组下标位置的值设置为null,
    33. //这样置空了引用,下次GC触发的时候,就会清理掉这些已经出栈的对象
    34. elements[size] = null;
    35. return result;
    36. }
    37. //扩容
    38. private void ensureCapacity() {
    39. //数组的length和 数组里面实际的元素个数一样了,就需要扩容了.
    40. if (elements.length == size)
    41. //数组复制操作
    42. elements = Arrays.copyOf(elements, 2 * size + 1);
    43. }
    44. }

    上面代码pop2方法会出现内存泄露问题,具体为什么内存泄露,看pop2方法注释,解决办法就是pop方法, pop方法就是pop2方法针对内存泄露的问题进行优化后的效果.

    pop2方法存在的问题:
    image.png
    pop2方法由于引用没有进行置空,GC是不会释放的,就向下面的图所示,这就会出现内存泄露的问题
    image.png