1. 程式人生 > >Java中四種引用(強、軟、弱、虛)

Java中四種引用(強、軟、弱、虛)

1. 強引用(StrongReference)

 強引用是使用最普遍的引用。如果一個物件具有強引用,那垃圾回收器絕不會回收它。當記憶體空間不足,Java虛擬機器寧願丟擲OutOfMemoryError錯誤,使程式異常終止,也不會靠隨意回收具有強引用的物件來解決記憶體不足的問題。

2. 軟引用(SoftReference)

如果一個物件只具有軟引用,則記憶體空間足夠,垃圾回收器就不會回收它;如果記憶體空間不足了,就會回收這些物件的記憶體。只要垃圾回收器沒有回收它,該物件就可以被程式使用。軟引用可用來實現記憶體敏感的快取記憶體

軟引用可以和一個引用佇列(ReferenceQueue)聯合使用,如果軟引用所引用的物件被垃圾回收器回收,Java虛擬機器就會把這個軟引用加入到與之關聯的引用佇列中。在垃圾回收之前/finalize()之前就會放入到引用佇列 ReferenceQueue.

3. 弱引用(WeakReference)

弱引用與軟引用的區別在於:只具有弱引用的物件擁有更短暫的生命週期。在垃圾回收器執行緒掃描它所管轄的記憶體區域的過程中,一旦發現了只具有弱引用的物件,不管當前記憶體空間足夠與否,都會回收它的記憶體。不過,由於垃圾回收器是一個優先順序很低的執行緒,因此不一定會很快發現那些只具有弱引用的物件

弱引用可以和一個引用佇列(ReferenceQueue)聯合使用,如果弱引用所引用的物件被垃圾回收,Java虛擬機器就會把這個弱引用加入到與之關聯的引用佇列中。  在垃圾回收之前/finalize()之前就會放入到引用佇列 ReferenceQueue.

4. 虛引用(PhantomReference)

"虛引用"顧名思義,就是形同虛設,與其他幾種引用都不同,虛引用並不會決定物件的生命週期。如果一個物件僅持有虛引用,那麼它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收。

虛引用主要用來跟蹤物件被垃圾回收器回收的活動。虛引用與軟引用和弱引用的一個區別在於:虛引用必須和引用佇列 (ReferenceQueue)聯合使用。當垃圾回收器準備回收一個物件時,如果發現它還有虛引用,就會在回收物件的記憶體之前,把這個虛引用加入到與之 關聯的引用佇列中。  

物件在垃圾回收/finalize()之後才會放入到ReferenceQueue中

總結:

WeakReference與SoftReference都可以用來儲存物件的例項引用,這兩個類與垃圾回收有關。


WeakReference是弱引用,其中儲存的物件例項可以被GC回收掉。這個類通常用於在某處儲存物件引用,而又不干擾該物件被GC回收,通常用於Debug、記憶體監視工具等程式中。因為這類程式一般要求即要觀察到物件,又不能影響該物件正常的GC過程。
最近在JDK的Proxy類的實現程式碼中也發現了Weakrefrence的應用,Proxy會把動態生成的Class例項暫存於一個由Weakrefrence構成的Map中作為Cache。

ThreadLocal的內部類ThreadLocalMap 中的Entry物件繼承了WeakReference,其key為ThreadLocal物件的虛引用,能夠保證當ThreadLocal物件的強引用消失後,ThreadLocal物件可以被回收,此時Entry物件的key為null,ThreadLocalMap也就可以回收此keyvalue了。

SoftReference是強引用,它儲存的物件例項,除非JVM即將OutOfMemory,否則不會被GC回收。這個特性使得它特別適合設計物件Cache。對於Cache,我們希望被快取的物件最好始終常駐記憶體,但是如果JVM記憶體吃緊,為了不發生OutOfMemoryError導致系統崩潰,必要的時候也允許JVM回收Cache的記憶體,待後續合適的時機再把資料重新Load到Cache中。這樣可以系統設計得更具彈性。