最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java引用類型WeakReference用法及原理詳解

 更新時(shí)間:2026年01月19日 09:53:39   作者:看透也說透kevin  
Java弱引用(WeakReference)是一種特殊的引用類型,當(dāng)垃圾回收器運(yùn)行時(shí),無論內(nèi)存是否充足,只要發(fā)現(xiàn)對(duì)象僅被弱引用指向,就會(huì)立即回收該對(duì)象,這篇文章主要介紹了java引用類型WeakReference用法及原理的相關(guān)資料,需要的朋友可以參考下

1. 核心概念:什么是 WeakReference?

WeakReference(弱引用)是 Java java.lang.ref 包下提供的一種引用類型。它的特點(diǎn)是:當(dāng)垃圾回收器(GC)進(jìn)行掃描時(shí),無論當(dāng)前內(nèi)存是否充足,只要被弱引用關(guān)聯(lián)的對(duì)象沒有其他強(qiáng)引用**,那么這個(gè)對(duì)象就會(huì)被回收。

這與我們平時(shí)普通的對(duì)象引用(強(qiáng)引用,Strong Reference)形成鮮明對(duì)比:

  • 強(qiáng)引用Object obj = new Object();。只要強(qiáng)引用存在,垃圾收集器就永遠(yuǎn)不會(huì)回收被引用的對(duì)象。
  • 弱引用WeakReference<Object> weakRef = new WeakReference<>(obj);。即使弱引用存在,只要發(fā)生 GC 且對(duì)象沒有強(qiáng)引用,它就會(huì)被回收。

2. 工作原理

WeakReference 的工作原理與 Java 的垃圾回收機(jī)制緊密相關(guān)。JVM 中的垃圾回收器使用可達(dá)性分析算法來判斷對(duì)象是否存活。

可達(dá)性分析:
GC Roots 是所有引用鏈的起點(diǎn)(如虛擬機(jī)棧中的局部變量、靜態(tài)變量等)。如果一個(gè)對(duì)象到 GC Roots 沒有任何引用鏈相連,則證明此對(duì)象是不可用的。

引用級(jí)別(強(qiáng)度從高到低):

  1. 強(qiáng)引用 (Strong Reference):絕不回收。
  2. 軟引用 (Soft Reference):內(nèi)存不足時(shí)(OOM 前)才回收。
  3. 弱引用 (Weak Reference)發(fā)現(xiàn)即回收。只要 GC 發(fā)現(xiàn)一個(gè)對(duì)象只被弱引用指向,就會(huì)立刻將其標(biāo)記為可回收對(duì)象,并在下一次 GC 時(shí)回收其內(nèi)存。
  4. 虛引用 (Phantom Reference):對(duì)象回收跟蹤。無法通過它獲取對(duì)象實(shí)例,其唯一目的是在對(duì)象被回收時(shí)收到一個(gè)系統(tǒng)通知。

WeakReference 的工作流程可以簡(jiǎn)化為:

  1. 你創(chuàng)建一個(gè)對(duì)象,并用一個(gè) WeakReference 來包裝它。
  2. 當(dāng)你將對(duì)象的強(qiáng)引用置為 nullobj = null;)后,這個(gè)對(duì)象就只剩下 WeakReference 這一個(gè)“微弱”的引用了。
  3. 下一次垃圾回收發(fā)生時(shí),GC 會(huì)發(fā)現(xiàn)這個(gè)對(duì)象是“弱可達(dá)”的。
  4. GC 會(huì)立即回收這個(gè)對(duì)象的內(nèi)存。
  5. 回收之后,你的 WeakReference.get() 方法將返回 null。

3. 主要用法和示例

基本使用

import java.lang.ref.WeakReference;

public class WeakReferenceDemo {
    public static void main(String[] args) {
        // 1. 創(chuàng)建一個(gè)強(qiáng)引用對(duì)象
        Object strongRef = new Object();

        // 2. 用弱引用包裝這個(gè)對(duì)象
        WeakReference<Object> weakRef = new WeakReference<>(strongRef);

        // 3. 此時(shí)既有強(qiáng)引用,也有弱引用。GC 不會(huì)回收它。
        System.out.println("Before GC (Strong ref exists): " + weakRef.get()); // 有輸出

        // 4. 切斷強(qiáng)引用!這是關(guān)鍵一步。
        strongRef = null;

        // 5. 建議系統(tǒng)進(jìn)行垃圾回收(這只是建議,不保證立即執(zhí)行)
        System.gc();

        // 6. 給 GC 一點(diǎn)時(shí)間執(zhí)行
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 7. 檢查弱引用指向的對(duì)象是否被回收
        System.out.println("After GC (Only weak ref): " + weakRef.get()); // 輸出 null
    }
}

輸出結(jié)果:

Before GC (Strong ref exists): java.lang.Object@1b6d3586
After GC (Only weak ref): null

典型應(yīng)用場(chǎng)景:實(shí)現(xiàn)內(nèi)存敏感的緩存

這是 WeakReference 最經(jīng)典的使用場(chǎng)景。你可以用它來構(gòu)建一個(gè)緩存,當(dāng)內(nèi)存不足時(shí),緩存中的條目會(huì)被自動(dòng)清除,從而避免內(nèi)存泄漏(Memory Leak)。

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;

public class SimpleCache<K, V> {
    private final Map<K, WeakReference<V>> cache = new HashMap<>();

    public void put(K key, V value) {
        cache.put(key, new WeakReference<>(value));
    }

    public V get(K key) {
        WeakReference<V> weakRef = cache.get(key);
        if (weakRef != null) {
            // 如果弱引用指向的對(duì)象還沒被GC回收,就返回它
            return weakRef.get();
        }
        // 如果被回收了或者不存在,就返回null
        return null;
    }

    // 可以添加一個(gè)方法來清理Map中那些已經(jīng)被GC回收的條目(key還在,value為null的Entry)
    public void cleanUp() {
        cache.entrySet().removeIf(entry -> entry.getValue().get() == null);
    }
}


為什么這樣用?

緩存的數(shù)據(jù)通常不是至關(guān)重要的。如果內(nèi)存緊張,丟棄部分緩存數(shù)據(jù)是可以接受的,應(yīng)用程序可以從原始數(shù)據(jù)源(如數(shù)據(jù)庫)重新加載。使用 WeakReference 可以讓 GC 充當(dāng)你的“緩存清理工”,自動(dòng)管理內(nèi)存,你無需編寫復(fù)雜的內(nèi)存淘汰算法(如 LRU)。

注意: 上面的 SimpleCache 中的 Map 本身仍然持有 key 的強(qiáng)引用和 WeakReference 對(duì)象的強(qiáng)引用。如果 key 本身是一個(gè)大對(duì)象,你可能需要類似 WeakHashMap 的結(jié)構(gòu)。

4. 注意事項(xiàng)

  1. 配合 ReferenceQueue 使用:你可以將一個(gè) ReferenceQueue 傳遞給 WeakReference 的構(gòu)造函數(shù)。當(dāng)弱引用指向的對(duì)象被垃圾回收后,這個(gè) WeakReference 對(duì)象本身會(huì)被加入到這個(gè)隊(duì)列中。這允許你執(zhí)行一些后續(xù)的清理工作,例如從緩存 Map 中移除對(duì)應(yīng)的鍵。

    ReferenceQueue queue = new ReferenceQueue<>();
    WeakReference weakRef = new WeakReference<>(new Object(), queue);
    // … 之后可以檢查 queue.poll() 來獲取被回收的引用

  2. 不是銀彈WeakReference 主要用于緩解內(nèi)存問題,而不是解決邏輯問題。你的代碼必須能處理 get() 返回 null 的情況(即對(duì)象已被回收)。

  3. 性能:頻繁創(chuàng)建 WeakReference 對(duì)象和進(jìn)行 GC 本身也有開銷,不要濫用。

  4. 與 SoftReference 的區(qū)別

    • WeakReference:GC 看到就回收,更激進(jìn)。
    • SoftReference:只有在內(nèi)存不足(即將發(fā)生 OOM)時(shí)才會(huì)回收,更適合做緩存,因?yàn)槟鼙M可能長時(shí)間地保留數(shù)據(jù)。而 WeakReference 的緩存被回收得更快。

總結(jié)

特性描述
本質(zhì)一種不影響垃圾回收決策的引用類型。
核心原則僅被弱引用關(guān)聯(lián)的對(duì)象,在 GC 時(shí)必定被回收。
主要用途實(shí)現(xiàn)規(guī)范化映射(如 WeakHashMap)、內(nèi)存敏感的高速緩存、監(jiān)聽器列表等,防止因緩存等原因?qū)е碌膬?nèi)存泄漏。
如何使用1. 創(chuàng)建 WeakReference 包裝對(duì)象。
2. 確保沒有其他強(qiáng)引用指向該對(duì)象。
3. 在代碼中總是檢查 get() 是否返回 null。

到此這篇關(guān)于java引用類型WeakReference用法及原理的文章就介紹到這了,更多相關(guān)java WeakReference用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring?Cloud?Gateway?2.x跨域時(shí)出現(xiàn)重復(fù)Origin的BUG問題

    Spring?Cloud?Gateway?2.x跨域時(shí)出現(xiàn)重復(fù)Origin的BUG問題

    這篇文章主要介紹了Spring?Cloud?Gateway?2.x跨域時(shí)出現(xiàn)重復(fù)Origin的BUG問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Java 線程池詳解及創(chuàng)建簡(jiǎn)單實(shí)例

    Java 線程池詳解及創(chuàng)建簡(jiǎn)單實(shí)例

    這篇文章主要介紹了Java 線程池詳解及創(chuàng)建簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • Spring?Boot?Interceptor的原理、配置、順序控制及與Filter的關(guān)鍵區(qū)別對(duì)比分析

    Spring?Boot?Interceptor的原理、配置、順序控制及與Filter的關(guān)鍵區(qū)別對(duì)比分析

    本文主要介紹了Spring?Boot中的攔截器(Interceptor)及其與過濾器(Filter)的區(qū)別,攔截器是Spring?MVC提供的接口,可以實(shí)現(xiàn)請(qǐng)求處理前后的邏輯,本文介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2025-12-12
  • Spring中基于xml的AOP實(shí)現(xiàn)詳解

    Spring中基于xml的AOP實(shí)現(xiàn)詳解

    這篇文章主要介紹了Spring中基于xml的AOP實(shí)現(xiàn)詳解,基于xml與基于注解的AOP本質(zhì)上是非常相似的,都是需要封裝橫切關(guān)注點(diǎn),封裝到切面中,然后把橫切關(guān)注點(diǎn)封裝為一個(gè)方法,再把該方法設(shè)置為當(dāng)前的一個(gè)通知,再通過切入點(diǎn)表達(dá)式定位到橫切點(diǎn)就可以了,需要的朋友可以參考下
    2023-09-09
  • 可能是全網(wǎng)最詳細(xì)的springboot整合minio教程

    可能是全網(wǎng)最詳細(xì)的springboot整合minio教程

    MinIO是全球領(lǐng)先的對(duì)象存儲(chǔ)先鋒,在標(biāo)準(zhǔn)硬件上,讀/寫速度上高達(dá)183 GB/秒和171 GB/秒,下面這篇文章主要給大家介紹了關(guān)于springboot整合minio的相關(guān)資料,這個(gè)教程可能是全網(wǎng)最詳細(xì)的,需要的朋友可以參考下
    2022-06-06
  • Java動(dòng)態(tài)數(shù)組ArrayList實(shí)現(xiàn)動(dòng)態(tài)原理

    Java動(dòng)態(tài)數(shù)組ArrayList實(shí)現(xiàn)動(dòng)態(tài)原理

    ArrayList是一種動(dòng)態(tài)數(shù)組,它可以在運(yùn)行時(shí)自動(dòng)調(diào)整大小以適應(yīng)元素的添加和刪除,在Java中,你可以使用ArrayList類來實(shí)現(xiàn)動(dòng)態(tài)數(shù)組,本文將給大家介紹一下ArrayList動(dòng)態(tài)數(shù)組,是怎么實(shí)現(xiàn)動(dòng)態(tài)的
    2023-08-08
  • 高分面試分析jvm如何實(shí)現(xiàn)多態(tài)

    高分面試分析jvm如何實(shí)現(xiàn)多態(tài)

    這篇文章主要介紹了講解了在面試中jvm如何實(shí)現(xiàn)多態(tài),怎樣回答才能得到高分的問題分析,有需要的朋友可以借鑒參考下,祝大家早日升職加薪多多進(jìn)步
    2022-01-01
  • intellij idea隱藏.iml和.idea等自動(dòng)生成文件的問題

    intellij idea隱藏.iml和.idea等自動(dòng)生成文件的問題

    這篇文章主要介紹了intellij idea隱藏.iml和.idea等自動(dòng)生成文件的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • IDEA創(chuàng)建Gradle項(xiàng)目然后刪除報(bào)錯(cuò)問題及解決

    IDEA創(chuàng)建Gradle項(xiàng)目然后刪除報(bào)錯(cuò)問題及解決

    這篇文章主要介紹了IDEA創(chuàng)建Gradle項(xiàng)目然后刪除報(bào)錯(cuò)問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Spring Cloud Config配置詳解

    Spring Cloud Config配置詳解

    這篇文章主要介紹了Spring Cloud Config配置詳解,Spring Cloud Config簡(jiǎn)化了配置管理的整個(gè)流程,包括配置的存放、獲取、變更通知、自動(dòng)刷新和安全保護(hù),需要的朋友可以參考下
    2026-05-05

最新評(píng)論

亚东县| 锦屏县| 井研县| 儋州市| 开鲁县| 凌源市| 来凤县| 台前县| 上杭县| 兴山县| 通山县| 宁安市| 蒙阴县| 肃宁县| 阜南县| 抚顺县| 太原市| 监利县| 镇远县| 增城市| 汉沽区| 乐昌市| 连南| 呼玛县| 金华市| 且末县| 河源市| 板桥市| 定陶县| 阿鲁科尔沁旗| 新余市| 柞水县| 尼木县| 璧山县| 佳木斯市| 宜春市| 镇远县| 舟山市| 渑池县| 神农架林区| 宝坻区|