天天看點

關于強引用、軟引用、弱引用與虛引用的一些知識

關于強引用、軟引用、弱引用與虛引用的一些知識

在Java中,除基本資料類型外,剩餘的都是指向各類對象的對象引用,因而按照其生命周期的長短,可進行引用分類。不同的引用類型主要展現的是對象不同的可達性狀态和對垃圾收集的影響。

1、強引用

  • 使用 new 建立的對象關聯的引用皆為強引用。
  • JVM出現記憶體不足時,即使抛出OOM異常終止程式也不會輕易回收具有強引用的對象來釋放記憶體。
  • 對于普通的對象,如果沒有其它的引用關系,隻要超過了引用的作用域或顯式将其對應引用指派為 null ,就可被垃圾回收器回收,具體回收時機由GC政策決定。

2、軟引用

  • 通過 SoftReference 類實作。
  • 生命周期短于強引用,當JVM認為記憶體不足時會去試圖回收軟引用指向的對象,以避免抛出OOM異常。
  • 軟引用可以和一個引用隊列(ReferenceQueue)聯合使用,如果軟引用所引用的對象被GC回收,Java虛拟機就會把這個軟引用加入到與之關聯的引用隊列中。後續可以調用 ReferenceQueue 的 poll() 方法來檢查是由有它關心的對象被回收。如果隊列為空,則傳回null,否則傳回隊列中前面的一個 Reference 對象。
  • 軟引用适用于作為記憶體敏感的緩存,若記憶體有空閑,則暫時保留緩存,當記憶體不足時則會被清理以保證記憶體不被耗盡。

3、弱引用

  • 通過 WeakReference 類實作。
  • 弱引用生命周期比軟引用短,當垃圾回收器線程掃描其負責的記憶體區域時,一旦發現具有弱引用的對象,就會立即對其進行回收,而不管目前記憶體是否充足與否。但由于垃圾回收器是一個優先級很低的線程,是以不一定會很快回收弱引用的對象。
  • 弱引用可與引用隊列(ReferenceQueue)聯合使用,如果弱引用被回收,Java虛拟機就會把這個弱引用加入相關聯的引用隊列中。
  • 适用記憶體敏感的緩存。

4、虛引用(幻象引用)

  • 通過 PhantomReference 類實作。
  • 我們無法通過虛引用通路對象的任何屬性或函數。虛引用僅提供一種在對象被finalize之後能做某些事情的機制。
  • 若一個對象僅持有虛引用則跟沒有持有任何引用引用,随時能被垃圾回收器回收。
  • 虛引用必須和引用隊列聯合使用,當GC準備回收一個對象時,若發現其還持有虛引用,則會在回收對象的記憶體之前,将這個虛引用加入到與之關聯的引用隊列中。
ReferenceQueue queue = new ReferenceQueue ();
PhantomReference pr = new PhantomReference (object, queue);
           
  • 程式可通過判斷引用隊列中是否以及加入了虛引用,來了解被引用的對象是否将被垃圾回收。若程式發現某個虛引用以及被加入到引用隊列,就可以在所引用的對象的記憶體被回收之前采取一些操作。
  • 虛引用适用于跟蹤對象被垃圾回收器回收的活動,當一個虛引用關聯的對象被垃圾回收器回收之前會收到通知。