天天看點

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

原文:http://blog.csdn.net/caijunjun1006/article/details/11935967

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中。這樣可以系統設計得更具彈性。