你知道 Java 有哪些引用嗎?

fuxing.發表於2024-05-17

前言

判斷物件是否要回收有引用計數法和可達性演算法兩種方式,無論哪種都離不開引用,本文將介紹Java的四種引用。


一、概述

image.png

image.png

二、詳解

1. 強引用

概述

在Java程式中,強引用是最常見的也是預設的。new了一個物件,並將其指向一個變數,這個變數就成為指向該物件的一個強引用。

特點

  1. 強引用可以直接訪問目標物件;
  2. 強引用所指向的物件在任何時候都不會被系統回收;
  3. 強引用可能導致記憶體洩漏。

實現方式

Object obj = new Object()	//這裡的obj就是一個強引用

2. 軟引用

概述

軟引用是用來描述一些還有用,但非必需的物件。只被軟引用關聯著的物件,在系統將要發生記憶體溢位異常前,會把這些物件列進回收範圍之中進行第二次回收,如果這次回收還沒有足夠的記憶體,才會丟擲記憶體溢位異常。

特點

  1. 軟引用所指向的物件,記憶體溢位前才被系統回收;
  2. 軟引用被回收後還沒有足夠的記憶體,仍會丟擲記憶體溢位異常;
  3. GC 決定收回軟可達物件時,會清理軟引用,並可選地把引用存放到一個引用佇列(Reference Queue)。

場景

軟引用通常用來實現記憶體敏感的快取。比如:可以使用軟引用來快取最近使用的圖片或文字,一旦記憶體不足,垃圾回收器就會回收這些物件,從而釋放記憶體。

實現方式

Object obj = new Object(); // 宣告強引用
SoftReference<Object> sf = new SoftReference<>(obj);
obj = null; //銷燬強引用

3. 弱引用

概述

弱引用也是用來描述那些非必需物件,但是在系統GC時,只要發現弱引用,不管系統堆空間使用是否充足,都會回收掉只被弱引用關聯的物件。 (但是,由於垃圾回收器的執行緒通常優先順序很低,因此,並不一定能很快地發現持有弱引用的物件。在這種情況下,弱引用物件可以存在較長的時間。)

特點

弱引用所指向的物件,被發現就會被系統回收;

場景

  1. 快取中存放的一些臨時的資料。如,ThreadLocal;
  2. 多執行緒中經常被用來監控物件是否被垃圾回收器標記。

實現方式

Object obj = new Object(); // 宣告強引用
WeakReference<Object> wf = new WeakReference<>(obj);
obj = null; //銷燬強引用

4. 虛引用

概述

所有引用型別中最弱的一個。一個物件是否有虛引用的存在,完全不會決定物件的生命週期。

特點

  1. 不能單獨使用,虛引用必須和引用佇列一起使用;
  2. 一個物件只被虛引用變數引用時,垃圾回收器會將該物件加入引用佇列中;
  3. 無法透過虛引用來獲取被引用的物件(當試圖透過虛引用的get()方法取得物件時,總是null)。

場景

在回收該物件之前,虛引用變數將被放入引用佇列中,因此通常用於在物件被回收時執行必要的清理工作。例如:

  1. 關閉資料庫連線或釋放資源在併發程式設計中;
  2. 實現一些高階的物件生命週期管理,例如,物件池和執行緒池等。(追蹤物件的生命週期,並在物件不再使用時及時清理它們,從而保證系統的可靠性和效能)

實現方式

Object obj = new Object(); // 宣告強引用
ReferenceQueue phantomQueue = new ReferenceQueue(); //須和引用佇列一起使用
PhantomReference<Object> pf = new PhantomReference<>(obj, phantomQueue);
obj = null;

相關文章