當(dāng)你從c&c++轉(zhuǎn)到一門具有垃圾回收功能的語(yǔ)言時(shí),程序員的工作就會(huì)變得更加容易,因?yàn)槟阌猛陮?duì)象,他們會(huì)被自動(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原因分析

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

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

1.

網(wǎng)友評(píng)論