消除过期的对象引用

虽然Java有垃圾回收机制,但有时也要考虑内存泄露问题。
// Can you spot the "memory leak"?

import java.util.*;

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);
    }
}

如果一个栈先是增长,然后再收缩,那么,从栈中弹出来的对象将不会被当做垃圾回收。
这是因为栈内部维护着对这些对象的 过期引用(obsolete reference),垃圾回收器无法分辨。
只要类是自己管理内存,程序员就应该警惕内存泄露问题。

修复方法:一旦对象引用过期,清空这些引用即可。
public Object pop() {
	if (size == 0)
		throw new EmptyStackException();
	Object result = elements[--size];
	elements[size] = null;	// Eliminate obsolete reference
	return result;
}

来自《Effective Java》
Item 6: Eliminate obsolete object references

你可能感兴趣的:(java)