Java 提供四種引用強度,為垃圾回收器提供靈活的內存管理策略,按生命週期由長到短:
| 引用類型 | 創建方式 | GC 回收時機 | 典型應用場景 |
|---|---|---|---|
| 強引用 | Object obj = new Object() | 永不主動回收(OOM 才拋棄) | 常規對象持有 |
| 軟引用 | SoftReference<T> ref = new SoftReference<>(obj) | 內存不足時回收 | 緩存、圖片加載池 |
| 弱引用 | WeakReference<T> ref = new WeakReference<>(obj) | 下次 GC 必回收 | WeakHashMap、監聽器 |
| 虛引用 | PhantomReference<T> ref = new PhantomReference<>(obj, queue) | GC 後進入引用隊列 | 堆外內存釋放、GC 監控 |
// 緩存場景:內存充足保留,不足自動清理 Map> imageCache = new HashMap<>(); public Bitmap getImage(String key) { SoftReference ref = imageCache.get(key); return ref != null ? ref.get() : null; // 可能返回 null }
// WeakHashMap:Key 為弱引用,GC 時自動移除條目 Mapcache = new WeakHashMap<>(); // 當 CacheKey 無強引用時,對應 Value 可被回收
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
public class PhantomRefDemo {
public static void main(String[] args) {
String obj = new String("DirectBuffer模擬");
ReferenceQueue queue = new ReferenceQueue<>();
PhantomReference phantom = new PhantomReference<>(obj, queue);
obj = null; // 切斷強引用
System.out.println(phantom.get()); // 永遠返回 null
System.gc(); // 強制 GC
System.runFinalization();
// 虛引用進入隊列,可在此釋放堆外資源
System.out.println(queue.poll() == phantom); // true
}
}
ReferenceQueue 是軟/弱/虛引用的協作橋樑:
queue.poll() 或阻塞 queue.remove()get() 永遠返回 null,不可用於獲取對象-XX:SoftRefLRUPolicyMSPerMB 可調節軟引用存活時間