過期的對象引用

消除過期的對象引用

修正前

public class Stack {

    public Object[] elements;
    
    public int size = 0;
    
    private static final int DEALULT_VLAUE = 16;

    public Stack() {
        elements = new Object[DEALULT_VLAUE];
    }

    public void push(Object e) {
        ensureCapacity();
        elements[size++] = e;
    }

    public Object pop() {
        if (size == 0) {
            throw new RuntimeException();
        }
        return elements[--size];
    }

    private void ensureCapacity() {
        if (elements.length == size) {
            elements = Arrays.copyOf(elements, 2 * size + 1);
        }
    }

}

這段程序中並沒有很明顯的錯誤.無論如何測試,它都會成功通過每一項測試.
但是! 這段程序有一個"內存泄漏"

解析

       // elements="Stack@539"
        Stack stack = new Stack();

        // elements[0]="1" size=1
        stack.push("1");

        // elements[0]="1" elements[1]="2" size=2
        stack.push("2");

        // elements[0]="1" elements[1]="2" size=1 pop="2"
        Object pop = stack.pop();

        // elements[0]="1" elements[1]="3" size=1
        stack.push("3");

從上方可以看出如果pop後沒有重新push那麼elements對象還在引用已經刪除的對象


內存泄漏-如果一個棧顯示增長,然後再收縮,那麼,從棧中彈出來的對象將不會被當做垃圾回收,即使使用的棧的程序不再引用這些對象,它們也不會被回收.這是因爲,棧內部維護着對這些對象的過期引用.
過期引用-,是指永遠也不會再被刪除的引用.


修正後

    public Object pop() {
        if (size == 0) {
            throw new RuntimeException();
        }
        Object result = elements[--size];
        elements[size] = null;
        return result;
    }

解析

       // elements="Stack@539"
        Stack stack = new Stack();

        // elements[0]="1" size=1
        stack.push("1");

        // elements[0]="1" elements[1]="2" size=2
        stack.push("2");

        // elements[0]="1" size=1 pop="2"
        Object pop = stack.pop();

        // elements[0]="1" elements[1]="3" size=1
        stack.push("3");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章