【发布时间】:2018-08-13 11:45:00
【问题描述】:
我正在阅读 Effective Java 第二版的“第 6 条:消除过时的对象引用”。
下面是代码sn-p。
//Can you spot the "memory leak"?
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];
}
/**
* Ensure space for at least one more element, roughly doubling the capacity
* each time the array needs to grow.
*/
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
根据这一项,内存泄漏是因为在popping 之后,数组索引没有被引用为NULL,如下所示:
public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; // Eliminate obsolete reference
return result;
}
我的理解是假设对于给定的数组,我已经完成 elements[0] = new Object() 然后我再次这样做 elements[0] = new Object() 然后我的第一个对象将有资格进行垃圾收集,因为我的数组的第 0 个索引不再指向它。
我的理解不正确吗?如果它是正确的,那么它是如何在 Effective Java 中显示为内存泄漏的。
【问题讨论】:
-
堆栈示例不同,因为它的想法是从无法再访问的 未使用 索引中删除对象引用。如果你只是将一个对象重新分配给一个仍然可以访问的索引,GC 最终会处理前一个对象。
标签: java memory memory-management memory-leaks garbage-collection