當你從c&c++轉到一門具有垃圾回收功能的語言時,程序員的工作就會變得更加容易,因為你用完對象,他們會被自動回收,但是,java程序員真的不需要考慮內存泄露嗎? 其實不然

1.舉個例子-看你能否找出內存泄漏

import java.util.Arrays;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);
    }
}

1.1原因分析

上述程序并沒有明顯的錯誤,但是這段程序有一個內存泄漏,隨著GC活動的增加,或者內存占用的不斷增加,程序性能的降低就會表現(xiàn)出來,嚴重時可導致內存泄漏,但是這種失敗情況相對較少。
代碼的主要問題在pop函數,下面通過這張圖示展現(xiàn)
假設這個棧一直增長,增長后如下圖所示
iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓
當進行大量的pop操作時,由于引用未進行置空,gc是不會釋放的,如下圖所示
iOS培訓,Swift培訓,蘋果開發(fā)培訓,移動開發(fā)培訓

從上圖中看以看出,如果棧先增長,在收縮,那么從棧中彈出的對象將不會被當作垃圾回收,即使程序不再使用棧中的這些隊象,他們也不會回收,因為棧中仍然保存這對象的引用,俗稱過期引用,這個內存泄露很隱蔽。

1.

網友評論