首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 7 四大引用類型全解析:強、軟、弱、虛引用與 GC 回收策略

     編輯:Java 綜合教學

Java 引用類型體系:從強到虛,精準控制對象生命周期

JDK 1.2 引入四種引用類型,配合 GC 實現靈活內存管理。按強度遞減:

強引用 > 軟引用 > 弱引用 > 虛引用

1. 強引用

Object obj = new Object(); // 最普遍
String str = "hello";
  • GC 絕不回收 有強引用指向的對象
  • 內存不足拋 OutOfMemoryError 也不回收
  • 手動斷開:obj = null 或離開作用域

實戰:ArrayList.clear() 源碼

public void clear() {
    modCount++;
    for (int i = 0; i < size; i++)
        elementData[i] = null; // 逐個置 null,釋放強引用
    size = 0;
}

優於 elementData = null:保留數組容量,避免擴容開銷。

2. 軟引用

SoftReference sr = new SoftReference<>("abc");
  • 內存夠用 → 不回收
  • 內存不足 → 回收
  • 適用:內存敏感緩存(圖片緩存、網頁緩存)

瀏覽器後退按鈕案例

BrowserPage page = loadPage(url);
SoftReference cache = new SoftReference<>(page);

// 用戶點後退
if (cache.get() != null) {
    show(cache.get()); // 緩存命中,極快
} else {
    page = loadPage(url); // 緩存被回收,重新加載
    cache = new SoftReference<>(page);
}

引用隊列

ReferenceQueue q = new ReferenceQueue<>();
SoftReference sr = new SoftReference<>("abc", q);
// 被回收後,sr 自動入隊 q
String ref = q.poll(); // 可輪詢處理回收後邏輯

3. 弱引用

WeakReference wr = new WeakReference<>("abc");
  • GC 掃描到即回收,無論內存是否充足
  • 生命周期更短,不阻礙對象被回收
  • 適用:非必須緩存、監聽器映射、ThreadLocal

WeakHashMap 原理

// Key 為弱引用,Key 無強引用時自動移除條目
Map cache = new WeakHashMap<>();
cache.put(new CacheKey("user:1"), data);
// CacheKey 無其他引用 → 下次 GC 後條目自動消失

4. 虛引用

PhantomReference pr = new PhantomReference<>(obj, queue);
  • 最弱,get() 永遠返回 null
  • 必須配合 ReferenceQueue 使用
  • 對象被回收前,虛引用入隊
  • 用途:精確感知對象回收時機、替代 finalize()、管理堆外內存

DirectByteBuffer 釋放堆外內存

// 內部持有 PhantomReference
// GC 回收 DirectByteBuffer 時,PhantomReference 入隊
// 專用線程輪詢隊列,調用 unsafe.freeMemory(address)

四大引用 GC 行為對比表

引用類型GC 回收時機get() 返回需隊列典型場景
強引用從不(除非 OOM)對象否正常業務對象
軟引用內存不足時對象/null可選高速緩存
弱引用下次 GC 時對象/null可選非必須映射、監聽器
虛引用下次 GC 時永遠 null必須回收追蹤、堆外內存釋放

GC 根可達性分析與引用鏈

GC Roots → 強引用鏈 → 對象(強可達,不回收)
GC Roots → 軟引用鏈 → 對象(軟可達,內存不足回收)
GC Roots → 弱引用鏈 → 對象(弱可達,必回收)
GC Roots → 虛引用鏈 → 對象(虛可達,必回收,入隊通知)

最佳實踐指南

  1. 默認強引用,業務核心對象
  2. 緩存用軟引用:Guava Cache、Caffeine 內部即基於軟/弱引用
  3. 監聽器/回調用弱引用:防止內存洩漏(如 WeakReference)
  4. 堆外內存/資源清理用虛引用:Netty、DirectByteBuffer、Cleaner (JDK 9+)
  5. 避免手動調用 System.gc():GC 觸發時機由 JVM 決定
  6. 引用隊列用於異步清理:而非同步阻塞業務線程

掌握四大引用,能讓你從「被動接受 GC」轉向「主動設計內存策略」,是高性能 Java 應用、中間件開發的必備內功。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved