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

Java 四大引用類型深度解析:強、軟、弱、虛引用與 GC 交互機制

     編輯:Java 綜合教學

引用類型層級與 GC 行為

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 時自動移除條目
Map cache = new WeakHashMap<>();
// 當 CacheKey 無強引用時,對應 Value 可被回收

虛引用:堆外內存釋放與 GC 追蹤

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 是軟/弱/虛引用的協作橋樑:

  • 對象被 GC 判定為可回收前,引用對象入隊
  • 單獨線程輪詢 queue.poll() 或阻塞 queue.remove()
  • 在入隊處理中執行清理邏輯(如釋放 DirectByteBuffer、關閉文件句柄)

實戰選型指南

  1. 需要緩存且希望內存壓力大時自動釋放 → SoftReference
  2. 需要映射關係不阻礙 Key 回收 → WeakReference / WeakHashMap
  3. 需要精確感知對象死亡、執行清理動作 → PhantomReference + ReferenceQueue
  4. 常規業務對象 → 強引用(默認)

注意事項

  • 虛引用 get() 永遠返回 null,不可用於獲取對象
  • 軟/弱引用配合緩存框架(Caffeine、Guava Cache)效果更佳
  • JVM 參數 -XX:SoftRefLRUPolicyMSPerMB 可調節軟引用存活時間
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved