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

Java中WeakHashMap的回收問題詳解

 更新時間:2023年09月07日 08:46:14   作者:幸平xp  
這篇文章主要介紹了Java中WeakHashMap的回收問題詳解,WeakHashMap弱鍵大致上是通過WeakReference和ReferenceQueue實(shí)現(xiàn),WeakHashMap的key是"弱鍵",即是WeakReference類型的,ReferenceQueue是一個隊(duì)列,它會保存被GC回收的"弱鍵",需要的朋友可以參考下

一、四大引用

在介紹WeakHashMap回收問題之前,我們要先介紹四大引用類型:

  • 強(qiáng)引用是最傳統(tǒng)的“引用”的定義,是指在程序代碼之中普遍存在的引用賦值,即類似“Object obj=new Object()”這種引用關(guān)系。無論任何情況下,只要強(qiáng)引用關(guān)系還存在,垃圾收集器就永遠(yuǎn)不會回 收掉被引用的對象。
  • 軟引用是用來描述一些還有用,但非必須的對象。只被軟引用關(guān)聯(lián)著的對象,在系統(tǒng)將要發(fā)生內(nèi)存溢出異常前,會把這些對象列進(jìn)回收范圍之中進(jìn)行第二次回收,如果這次回收還沒有足夠的內(nèi)存, 才會拋出內(nèi)存溢出異常。在JDK 1.2版之后提供了SoftReference類來實(shí)現(xiàn)軟引用。
  • 弱引用也是用來描述那些非必須對象,但是它的強(qiáng)度比軟引用更弱一些,被弱引用關(guān)聯(lián)的對象只 能生存到下一次垃圾收集發(fā)生為止。當(dāng)垃圾收集器開始工作,無論當(dāng)前內(nèi)存是否足夠,都會回收掉只 被弱引用關(guān)聯(lián)的對象。在JDK 1.2版之后提供了WeakReference類來實(shí)現(xiàn)弱引用。
  • 虛引用也稱為“幽靈引用”或者“幻影引用”,它是最弱的一種引用關(guān)系。一個對象是否有虛引用的 存在,完全不會對其生存時間構(gòu)成影響,也無法通過虛引用來取得一個對象實(shí)例。為一個對象設(shè)置虛 引用關(guān)聯(lián)的唯一目的只是為了能在這個對象被收集器回收時收到一個系統(tǒng)通知。在JDK 1.2版之后提供 了PhantomReference類來實(shí)現(xiàn)虛引用。

對于本文主要涉及的為強(qiáng)引用,弱引用。其他引用本篇就不再多提了。 總結(jié)一下強(qiáng)引用與弱引用:

  • 強(qiáng)引用:主要為new出來的對象,就算內(nèi)存滿了,也不會回收它。因此當(dāng)強(qiáng)引用過多時會導(dǎo)致OOM(內(nèi)存溢出),HashMap中key、value關(guān)系就為強(qiáng)引用。
  • 弱引用:被弱引用關(guān)聯(lián)的對象只 能生存到下一次垃圾收集發(fā)生為止,而WeakHashMap中的key,value就是弱引用關(guān)系。

二、WeakHashMap的回收問題

首先基本大概講述一下WeakHashMap弱鍵的原理:

大致上是通過WeakReference和ReferenceQueue實(shí)現(xiàn)的。WeakHashMap的key是“弱鍵”,即是WeakReference類型的;ReferenceQueue是一個隊(duì)列,它會保存被GC回收的“弱鍵”。

實(shí)現(xiàn)步驟是:

1、新建WeakHashMap,將“鍵值對”添加到WeakHashMap中。實(shí)際上,WeakHashMap是通過數(shù)組table保存Entry(鍵值對);每一個Entry實(shí)際上是一個單向鏈表,即Entry是鍵值對鏈表。

2、當(dāng)某“弱鍵”不再被其它對象引用,并被GC回收時。在GC回收該“弱鍵”時,這個“弱鍵”也同時會被添加到ReferenceQueue(queue)隊(duì)列中。

3、 當(dāng)下一次我們需要操作WeakHashMap時,會先同步table和queue。table中保存了全部的鍵值對,而queue中保存被GC回收的鍵值對;同步它們,就是刪除table中被GC回收的鍵值對。這就是“弱鍵”如何被自動從WeakHashMap中刪除的步驟了。和HashMap一樣,WeakHashMap是不同步的??梢允褂?Collections.synchronizedMap 方法來構(gòu)造同步的 WeakHashMap。

讀者看到這可能還是比較抽象。沒關(guān)系,接下來我們直接上一些例子:

public static void main(String[] args) {
        WeakHashMap<String,String> weakMap = new WeakHashMap<>();
        weakMap.put("k1","v1");
        String k2 = new String("k2");
        weakMap.put(k2,"v2");
        weakMap.put(new String("k3"),"k3");
        System.out.println("weakMap回收前打印結(jié)果:");
        System.out.println(weakMap);
        // 因?yàn)閃eakHashMap內(nèi)部維護(hù)的是一個弱引用映射所以gc直接回收
        System.gc();
        System.out.println("weakMap回收后打印結(jié)果:");
        System.out.println(weakMap);
    }

以上的打印結(jié)果是什么呢?

在這里插入圖片描述

可以看到打印結(jié)果是回收后的結(jié)果是只有k3的key-value被回收掉了。那么為什么呢?

這得首先從創(chuàng)建一個String對象說起,創(chuàng)建一個String對象最常見的有兩種情況:

// 第一種情況
String str1 = "a";
// 第二種情況
String str2 = new String("b");

對于第一種情況其對象的創(chuàng)建會先在字符串常量池判斷有沒有對應(yīng)的字符串常量,如果沒有創(chuàng)建一個字符串常量一,然后將其引用指向在字符串常量池中的那個常量,如果存在則不需創(chuàng)建直接返回引用。 對于第二種情況其對象的引用還是會先在字符串常量池判斷有沒有對應(yīng)的字符串常量,如果沒有創(chuàng)建一個字符串常量。 而后在堆中拷貝一個其字符串常量的對象,最后返回堆上的引用。

我畫了張圖對于情況二來講應(yīng)該是這個:

在這里插入圖片描述

那么對于對象創(chuàng)建的引用我們了解了,那么接下來回到例子就很好理解。

  • 首先是 weakMap.put(“k1”,“v1”); 很明顯這里面是k1的引用是放在字符串常量池里的,是一種強(qiáng)引用。因此關(guān)于k1的key會一直保持下去。所以就是強(qiáng)引用,因此不會被gc。

然后則是:

String k2 = new String("k2");
weakMap.put(k2,"v2");

這里面的很明顯k2為new String的WeakHashMap外部的強(qiáng)引用,因此k2的指針其實(shí)是在WeakHashMap外部被引用,所以不會被gc。如果要回收它也很容易,則只需要將其外部的引用k2置為null

String k2 = new String("k2");
weakMap.put(k2,"v2");
k2 = null;

而相對直接在WeakHashMap內(nèi)直接創(chuàng)建對象返回引用的話,那么很明顯就是弱鍵了。

weakMap.put(new String("k3"),"k3");

那么如何可以如何才能不回收這個字符串對象呢?我們剛剛畫圖提到了,我們可以用intern()方法返回其字符串常量池對應(yīng)的對象。

weakMap.put(new String("k3").intern(),"k3");

這個時候小伙伴可以自己去試一下,此時這個對象gc后也不會被回收了。就如同情況1:weakMap.put(“k1”,“v1”);

最后的最后附上完整代碼,有興趣的可以自己去試試:

public class MapGC {
    public static void main(String[] args) {
        WeakHashMap<String,String> weakMap = new WeakHashMap<>();
        weakMap.put("k1","v1");
        String k2 = new String("k2");
        weakMap.put(k2,"v2");
        weakMap.put(new String("k3"),"k3");
        System.out.println("weakMap回收前打印結(jié)果:");
        System.out.println(weakMap);
        // 因?yàn)閃eakHashMap內(nèi)部維護(hù)的是一個弱引用映射所以gc直接回收
        System.gc();
        System.out.println("weakMap第一次回收后打印結(jié)果:");
        System.out.println(weakMap);
        k2 = null;
        weakMap.put(new String("k3").intern(),"k3");
        System.gc();
        System.out.println("weakMap第二次回收后打印結(jié)果:");
        System.out.println(weakMap);
    }
}

輸出結(jié)果:

在這里插入圖片描述

到此這篇關(guān)于Java中WeakHashMap的回收問題詳解的文章就介紹到這了,更多相關(guān)WeakHashMap回收內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mybatis分頁及模糊查詢功能實(shí)現(xiàn)

    mybatis分頁及模糊查詢功能實(shí)現(xiàn)

    這篇文章主要為大家詳細(xì)為大家詳細(xì)介紹了mybatis實(shí)現(xiàn)分頁及模糊查詢功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • java使用Jsoup連接網(wǎng)站超時的解決方法

    java使用Jsoup連接網(wǎng)站超時的解決方法

    jsoup是一個非常好的解析網(wǎng)頁的包,用java開發(fā)的,提供了類似DOM,CSS選擇器的方式來查找和提取文檔中的內(nèi)容,提取文檔內(nèi)容時會出現(xiàn)超時的情況,解決方法可看下文
    2013-11-11
  • Java應(yīng)用如何防止惡意文件上傳

    Java應(yīng)用如何防止惡意文件上傳

    惡意文件上傳可能導(dǎo)致服務(wù)器被入侵,數(shù)據(jù)泄露甚至服務(wù)癱瘓,因此我們必須采取全面且有效的防范措施來保護(hù) Java 應(yīng)用的安全,下面我們就來看看具體的實(shí)現(xiàn)方法吧
    2025-05-05
  • Java之Zookeeper注冊中心原理剖析

    Java之Zookeeper注冊中心原理剖析

    這篇文章主要介紹了Java之Zookeeper注冊中心原理剖析,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • PageHelper在springboot+mybatis框架中的使用步驟及原理解析

    PageHelper在springboot+mybatis框架中的使用步驟及原理解析

    這篇文章主要介紹了PageHelper在springboot+mybatis框架中的使用步驟及原理解析,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • SpringBoot項(xiàng)目的多文件兼多線程上傳下載

    SpringBoot項(xiàng)目的多文件兼多線程上傳下載

    本文主要介紹了SpringBoot項(xiàng)目的多文件兼多線程上傳下載,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • org.apache.ibatis.annotations不存在的問題

    org.apache.ibatis.annotations不存在的問題

    這篇文章主要介紹了org.apache.ibatis.annotations不存在的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • 詳解maven安裝教程以及解決安裝不成功的解決辦法

    詳解maven安裝教程以及解決安裝不成功的解決辦法

    這篇文章主要介紹了詳解maven安裝教程以及解決安裝不成功的解決辦法,詳細(xì)的介紹了幾種解決方法,非常具有實(shí)用價值,需要的朋友可以參考下
    2018-12-12
  • 關(guān)于Integer.parseInt()方法的使用

    關(guān)于Integer.parseInt()方法的使用

    這篇文章主要介紹了關(guān)于Integer.parseInt()方法的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • MyBatis 管理和查找TypeHandler的方法

    MyBatis 管理和查找TypeHandler的方法

    MyBatis通過TypeHandlerRegistry組件集中管理和查找TypeHandler,TypeHandler用于處理Java類型和JDBC類型之間的轉(zhuǎn)換,本文介紹MyBatis 管理和查找TypeHandler的方法,感興趣的朋友一起看看吧
    2025-03-03

最新評論

惠东县| 内乡县| 万荣县| 且末县| 平度市| 中西区| 旺苍县| 遂宁市| 务川| 民勤县| 德令哈市| 泰顺县| 遵义市| 蓬莱市| 微山县| 兰考县| 宝清县| 砚山县| 百色市| 贵南县| 会昌县| 泽库县| 新乡县| 谢通门县| 曲周县| 佛山市| 海晏县| 邯郸市| 长春市| 东乌珠穆沁旗| 当雄县| 涞源县| 镇江市| 龙南县| 遂平县| 英德市| 廉江市| 奉化市| 米脂县| 平南县| 永春县|