在下面这段代码中存在一个内存泄漏的问题,在使用中表现为性能下降,在极端情况下甚至可能出现 OutOfMemoryError。先看代码,看你是否能够找出其中内存泄漏的部分。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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);
    }
}

在这段代码中,elements 中弹出的元素并不会真正的被垃圾回收器回收,这是由于 elements 依然持有对该对象的引用。将 pop() 改成弹出对象时,顺便将该引用置为 null 即可解决这个问题。

1
2
3
4
5
    public Object pop() {
        if (size == 0) throw new EmptyStackException();
        Object result = elements[--size];
        elements[size] = null; // Eliminate obsolete reference return result;
    }