java中的持有引用

來源:互聯網
上載者:User

Thinking in java對這個地方說得不清楚,隨便在網上找了幾篇文章也沒看太明白。

是說想要在以後訪問某個對像,但現在又想先回收了它,就可以使用持有引用來實現,而問題是回收就是回收了,怎麼才能之後再訪問到呢?沒人說明。

深入尋找資料之後發現上面的認識是錯誤的!

持有引用的作用是在執行gc之後允許你繼續持有(可能)被回收了的對象的引用,而將對像執行個體清出記憶體,持有引用提供了與記憶體回收行程之間有限的互動。

記憶體回收概述

記憶體回收行程在回收對象之前需要判斷一個對象是否存活,java中使用根搜尋演算法來判斷。基本思想是對過一系列名為GC Roots的對象作為起始點,從這些節點向下搜尋,當一個對象不能被任何一個GC Roots到達時就認為該對象是可回收的。然而您還需要注意一個重要的細節:僅憑對象可以被收集並不意味著垃圾收集器的一次指定運行就能夠回收它。由於各種垃圾收集演算法有所不同,某些演算法會更頻繁地分析生存期較短的對象,而不是較老、生存期較長的對象。因此,一個可供收集的對象可能永遠也不會被回收。如果程式在垃圾收集器釋放對象之前結束,這種情況就可能會出現。因此,概括地說,您永遠無法保證可供收集的對象總是會被垃圾收集器收集。

一些術語:

  • 強可及對象(strongly reachable):可以通過強引用訪問的對象。
  • 軟可及對象(softly reachable):不是強可及對象,並且能夠通過軟引用訪問的對象。
  • 弱可及對象(weakly reachable):不是強可及對象也不是軟可及對象,並且能夠通過弱引用訪問的對象。
  • 虛可及對象(phantomly reachable):不是強可及對象、軟可及對象,也不是弱可及對象,已經結束的,可以通過虛引用訪問的對象。
  • 清除:將引用對象的 referent 網域設定為 null ,並將引用類在堆中引用的對象聲明為
    可結束的
    。 

java.lang.ref包中提供了三個類來達到三種不同的參考型別:

SoftReference 類

SoftReference 類的一個典型用途就是用於記憶體敏感的快取。
SoftReference 的原理是:在保持對對象的引用時保證在 JVM 報告記憶體不足情況之前將清除所有的軟引用。關鍵之處在於,垃圾收集器在運行時可能會(也可能不會)釋放軟可及對象。對象是否被釋放取決於垃圾收集器的演算法以及垃圾收集器運行時可用的記憶體數量。

WeakReference 類

WeakReference 類的一個典型用途就是正常化映射(canonicalized mapping)。另外,對於那些生存期相對較長而且重新建立的開銷也不高的對象來說,弱引用也比較有用。關鍵之處在於,垃圾收集器運行時如果碰到了弱可及對象,將釋放
WeakReference 引用的對象。然而,請注意,垃圾收集器可能要運行多次才能找到並釋放弱可及對象。

PhantomReference 類

PhantomReference 類只能用於跟蹤對被引用對象即將進行的收集。同樣,它還能用於執行 pre-mortem 清除操作。
PhantomReference 必須與 ReferenceQueue 類一起使用。需要 ReferenceQueue 是因為它能夠充當通知機制。當垃圾收集器確定了某個對象是虛可及對象時,
PhantomReference 對象就被放在它的 ReferenceQueue 上。將 PhantomReference 對象放在
ReferenceQueue 上也就是一個通知,表明 PhantomReference 對象引用的對象已經結束,可供收集了。這使您能夠剛好在對象佔用的記憶體被回收之前採取行動。 

以上有兩點需要說明,一是SoftReference用於快取可以理解為維護了一組動態記憶體,這塊記憶體中的對象在需要是可以被gc回收而不會存在強引用指向它們。第二點是正常化映射是什嗎?它是指你可以使用WeakReference來建立一組映射,而這組映射裡的對象是可以被回收的,比如當我們正常的建立一個Map時,向裡面添加對象,被添加的這些對象是由它們的容器Map可達的,所以就不能被回收,而如果通過WeakReference封裝對象然後再添加到Map中,這些對象就可以被回收了,具體請看這裡:http://c2.com/cgi/wiki?CanonicalizedMapping。

下面在這裡看與記憶體回收行程的互動及持有引用的使用方法:Java 2 引用類使用指南 https://www.ibm.com/developerworks/cn/java/j-refs/,這篇文章裡面說明了持有引用的原理和使用持有引用的正確方法。

使用Reference API:

The Reference Objects API allows programs to interact with the garbage collectorhttp://www.javaworld.com/javaworld/jw-01-2002/jw-0104-java101.html?page=2

另外java提供了WeakHashMap來實現規範映射,這與使用WeakReference的實現達到同樣的效果,值得注意的一點就是這時需要運行再次記憶體回收才能把key(第一次回收)和value(第二次回收)回收掉。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.