當(dāng)你從c&c++轉(zhuǎn)到一門具有垃圾回收功能的語言時(shí),程序員的工作就會變得更加容易,因?yàn)槟阌猛陮ο螅麄儠蛔詣?dòng)回收,但是,java程序員真的不需要考慮內(nèi)存泄露嗎? 其實(shí)不然

1.舉個(gè)例子-看你能否找出內(nèi)存泄漏

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原因分析

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

從上圖中看以看出,如果棧先增長,在收縮,那么從棧中彈出的對象將不會被當(dāng)作垃圾回收,即使程序不再使用棧中的這些隊(duì)象,他們也不會回收,因?yàn)闂V腥匀槐4孢@對象的引用,俗稱過期引用,這個(gè)內(nèi)存泄露很隱蔽。

1.