消除過期的對(duì)象引用

你能看出以下代碼哪里內(nèi)存泄漏嗎?

// Can you spot the "memory leak"?
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);
    }
}

答案是:

pop()方法存在內(nèi)存泄漏。

內(nèi)存泄漏可以稱為“ 無意識(shí)的對(duì)象保持(unintentional object retention)”。
在pop()方法中從棧中彈出來的對(duì)象將不會(huì)被當(dāng)做垃圾回收。棧內(nèi)部維護(hù)著對(duì)這些對(duì)象的過期引用(obsolete reference)。所謂的過期引用,是指永遠(yuǎn)也不會(huì)再被解除的引用。凡是在elements數(shù)組的“活動(dòng)部分”(active portion)之外的任何引用都是過期的?;顒?dòng)部分是指elements中下標(biāo)小于size的那些元素。

解決方法:上述述例子中的Stack類而言,只要一個(gè)單元被彈出棧,指向它的引用就過期了。一旦數(shù)組元素變成了非活動(dòng)部分的一部分,就手工清空這些數(shù)組元素。修改后的pop()方法如下:

public Object pop() {
    if (size == 0)
        throw new EmptyStackException();
    Object result = elements[--size];//result相當(dāng)于一個(gè)temp。
    elements[size] = null; // Eliminate obsolete reference
    return result;
}

清空對(duì)象引用應(yīng)該是一種例外,而不是一種規(guī)范行為。消除過期引用最好的方法是讓包含該引用的變量結(jié)束其生命周期。

延伸閱讀

length、size()、length()的區(qū)別:

  • 數(shù)組的長度(length):數(shù)組能容納元素個(gè)數(shù)的值
  • 泛型集合的大?。╯ize()):泛型中元素的個(gè)數(shù)
  • 字符串的長度(length()):字符的個(gè)數(shù)

前綴遞減和后綴遞增:

  • 前綴遞減,"--"操作符位于變量或表達(dá)式前,先執(zhí)行運(yùn)算,再生成值。如上例中elements[--size],size大小先減1,所以Object result = elements[--size];中result元素下標(biāo)為size=size-1。
  • 后綴遞增,"++"操作符位于變量或表達(dá)式后,先生成值,再執(zhí)行運(yùn)算。如上例中elements[size++] = e;,元素下標(biāo)為size,再執(zhí)行運(yùn)算size=size+1。

Arrays.copyOf()方法:

  • a copy of the original array, truncated or padded with nulls to obtain the specified length(原始數(shù)組的副本,縮短或填補(bǔ)null來獲取指定的長度)。
  • 作用:如果數(shù)組元素的個(gè)數(shù)等于數(shù)組的長度,新建副本數(shù)組,將長度擴(kuò)大為兩倍加一,將數(shù)組副本賦值給elements。

參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容