Java 中的引用型別:強引用、軟引用、弱引用和虛引用
Java 中的引用型別主要分為 強引用、軟引用、弱引用 和 虛引用,它們對物件的生命週期和垃圾回收(GC)行為產生不同的影響。
1. 強引用(Strong Reference)
定義
強引用是 Java 中最常見的引用型別。透過賦值運算子 =
建立的普通引用即為強引用。
特點
- 只要強引用存在,垃圾回收器(GC)就不會回收引用指向的物件。
- 強引用物件通常儲存在堆記憶體中。
示例
public class StrongReferenceExample {
public static void main(String[] args) {
Object obj = new Object(); // 強引用
System.out.println(obj); // 強引用存在,obj 不會被回收
}
}
2. 軟引用(Soft Reference)
定義
軟引用是一種相對較弱的引用型別,可透過 java.lang.ref.SoftReference
類實現。
特點
- 軟引用指向的物件在記憶體不足時才會被 GC 回收(適合實現快取)。
- 軟引用可以延長一些大物件的生命週期,直到 JVM 記憶體不足。
示例
import java.lang.ref.SoftReference;
public class SoftReferenceExample {
public static void main(String[] args) {
Object obj = new Object();
SoftReference<Object> softRef = new SoftReference<>(obj);
obj = null; // 去掉強引用
System.out.println(softRef.get()); // 軟引用仍然可用
// 在記憶體不足時,softRef 可能會被回收
}
}
注意
- 軟引用常用於實現記憶體敏感的快取機制。
3. 弱引用(Weak Reference)
定義
弱引用是一種比軟引用更弱的引用型別,可透過 java.lang.ref.WeakReference
類實現。
特點
- 只要 GC 發現弱引用物件沒有強引用或軟引用關聯時,立即回收。
- 通常用於實現規範化對映(如
WeakHashMap
)。
示例
import java.lang.ref.WeakReference;
public class WeakReferenceExample {
public static void main(String[] args) {
Object obj = new Object();
WeakReference<Object> weakRef = new WeakReference<>(obj);
obj = null; // 去掉強引用
System.out.println(weakRef.get()); // 弱引用仍然可用
System.gc(); // 顯式呼叫 GC
System.out.println(weakRef.get()); // 弱引用可能被回收,返回 null
}
}
注意
- 弱引用非常適合使用在快取或動態代理中。
4. 虛引用(Phantom Reference)
定義
虛引用是一種最弱的引用型別,可透過 java.lang.ref.PhantomReference
類實現。
特點
- 虛引用不會決定物件的生命週期。
- 主要用於跟蹤物件被回收的時間點。
- 虛引用必須與引用佇列(
ReferenceQueue
)一起使用。
示例
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
public class PhantomReferenceExample {
public static void main(String[] args) {
Object obj = new Object();
ReferenceQueue<Object> queue = new ReferenceQueue<>();
PhantomReference<Object> phantomRef = new PhantomReference<>(obj, queue);
obj = null; // 去掉強引用
System.gc(); // 顯式呼叫 GC
// 虛引用本身無法透過 get() 方法獲取物件
System.out.println(phantomRef.get()); // 始終返回 null
}
}
注意
- 虛引用常用於清理工作或監控物件的回收狀態。
5. 引用型別的對比
引用型別 | 描述 | 對 GC 的影響 | 適用場景 |
---|---|---|---|
強引用 | 預設的引用型別,物件存活取決於引用 | GC 永遠不會回收 | 常規物件引用 |
軟引用 | 記憶體不足時回收 | 記憶體不足時 GC 可能回收 | 快取實現 |
弱引用 | 只要 GC 發現,立即回收 | 只要無強引用或軟引用時,立即回收 | WeakHashMap、動態代理等 |
虛引用 | 無法直接訪問物件,僅用於回收跟蹤 | GC 回收後加入 ReferenceQueue | 清理資源、監控物件回收狀態 |
6. 總結
- 強引用:最常見的引用型別,保證物件不被回收。
- 軟引用:記憶體敏感的引用,適合快取場景。
- 弱引用:短生命週期的引用,適合規範化對映或動態代理。
- 虛引用:僅用於監控物件的回收,適合清理或跟蹤任務。