關(guān)于WeakhashMap與HashMap之間的區(qū)別和聯(lián)系
Java中四大引用:(強(qiáng)>軟>弱>虛)
- 強(qiáng)引用
//A a是創(chuàng)建一個(gè)引用,new A()是開(kāi)辟一塊地址空間存放引用的對(duì)象 , A a = new A(); //a是強(qiáng)引用,只要是強(qiáng)引用,GC(即垃圾回收)就不會(huì)回收被引用的對(duì)象(即new A())
- 軟引用SoftReference
一般用于實(shí)現(xiàn)Java對(duì)象的緩存,緩存可有 可無(wú),一般將有用但是非必須的對(duì)象用 軟引用關(guān)聯(lián),只要是軟引用關(guān)聯(lián)的對(duì)象,在Java發(fā)生 內(nèi)存溢出 異常之前,會(huì)將這些對(duì)象列入要 回收的范圍(即內(nèi)存不夠才回收),如果回收之后發(fā)現(xiàn)內(nèi)存還是不夠,才會(huì)拋出OOM異常,用軟引用關(guān)聯(lián)起來(lái),使用時(shí)直接get,就不用每次創(chuàng)建 。例如 假設(shè)map頻繁被使用 -》可用 SoftReference關(guān)聯(lián) -》 用 SoftReference.get()獲取該對(duì)象,以便調(diào)用其方法
- 弱引用 WeakReference
弱引用是用來(lái)一些非必須的對(duì)象,比軟引用更弱一些,只要是被弱引用關(guān)聯(lián)的對(duì)象,只能夠生存到下一次垃圾回收之前,一旦發(fā)生垃圾回收,無(wú)論當(dāng)前內(nèi)存是否夠用,都會(huì)回收掉被弱引用關(guān)聯(lián)的對(duì)象
- 虛引用 PhantomReference
別名幽靈引用 最弱的引用關(guān)系,一個(gè)對(duì)象是否具有虛引用的存在,完全是不會(huì)對(duì)其生命周期產(chǎn)生影響,也無(wú)法通過(guò)虛引用獲取一個(gè)對(duì)象的實(shí)例,它存在的唯一目的就是在對(duì)象被垃圾回收之后收到一個(gè)系統(tǒng)通知
特殊的HashMap:WeakHashMap
鍵是弱引用對(duì)象,只能存活到下一次垃圾回收之前;
被回收的鍵放在 ReferenceQueue里,在HashMap里,會(huì) 根據(jù)ReferenceQueue里的值,把鍵對(duì)應(yīng)的value找到,然后把結(jié)點(diǎn)移除,同時(shí)讓當(dāng)前的value不要引用原先的對(duì)象,這些對(duì)象才能在下一次垃圾回收時(shí)再被回收掉
代碼測(cè)試
package collection; import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.WeakHashMap; class MyArray{ byte[] bytes = new byte[3*1024*1024]; //即占用3M } class Test{ } public class TestReference { public static void main(String[] args) { // //引用隊(duì)列 // //將軟引用對(duì)象關(guān)聯(lián)成一個(gè)key值,添加到隊(duì)列里,遍歷 隊(duì)列中每個(gè)元素分別找到其在 HashMap里的位置,然后把結(jié)點(diǎn)(key,value)完全刪除掉 // ReferenceQueue<MyArray> queue = new ReferenceQueue<>(); // //創(chuàng)建一個(gè)軟引用對(duì)象 // SoftReference<MyArray> softReference = new SoftReference<>(new MyArray(), queue);//當(dāng)對(duì)象被回收時(shí),會(huì)直接入到queue里 // //獲取軟引用對(duì)象(softReference) // System.out.println(softReference.get()); // //判斷是否被回收(true 被回收 入到隊(duì)列) // System.out.println(softReference.isEnqueued()); // // -Xms3M -Xmx5M 即初始給堆3M空間,最大是5M空間 右鍵-》 run configurations——》設(shè)置虛擬機(jī)參數(shù) // //System.gc();//可模擬垃圾回收 // byte[] array = new byte[3*1024*1024]; // // System.out.println(softReference.get()); // System.out.println(softReference.isEnqueued()); // // 弱引用對(duì)象 // ReferenceQueue<Test> queue = new ReferenceQueue<>(); // WeakReference<Test> weakReference = new WeakReference<>(new Test(), queue); // // System.out.println(weakReference.get()); // System.out.println(weakReference.isEnqueued()); // // System.gc(); // // System.out.println(weakReference.get()); // System.out.println(weakReference.isEnqueued()); // // //虛引用對(duì)象 // ReferenceQueue<Test> queue = new ReferenceQueue<>(); // PhantomReference<Test> phantomReference = new PhantomReference<>(new Test(), queue); // //進(jìn)程的執(zhí)行,需要線(xiàn)程的支持 // //垃圾回收作為一個(gè)線(xiàn)程(等CPU分配時(shí)間片)支持虛擬機(jī)的執(zhí)行 // //JDK(或虛擬機(jī))里垃圾回收線(xiàn)程是隨機(jī)啟動(dòng)的,調(diào)用 System.gc();可以手動(dòng)回收 // System.gc(); // if(phantomReference.isEnqueued()){ // System.out.println("該對(duì)象已經(jīng)被回收"); // }else{ // System.out.println("該對(duì)象已經(jīng)被回收"); // } } }
類(lèi)的繼承關(guān)系
HashMap中的對(duì)象可以被拷貝 克隆 序列到磁盤(pán)上,WeakhashMap都不行
重要方法
- WeakhashMap的put方法(key重復(fù),新值覆蓋舊值;頭插新節(jié)點(diǎn))
- hash算法不一樣(WeakhashMap源碼297行 )
/** * Retrieve object hash code and applies a supplemental hash function to the * result hash, which defends against poor quality hash functions. This is * critical because HashMap uses power-of-two length hash tables, that * otherwise encounter collisions for hashCodes that do not differ * in lower bits. */ final int hash(Object k) { int h = k.hashCode(); // This function ensures that hashCodes that differ only by // constant multiples at each bit position have a bounded // number of collisions (approximately 8 at default load factor). h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); }
//HashMap337行 static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }
- put(447行)不能放鍵為NULL,系統(tǒng)會(huì)自動(dòng)new一個(gè) NULLKEY,HashMap的key和value都可以為null;
- WeakhashMap中的put/get/remove/resize等方法均會(huì)使用expungeStaleEntries()方法,用來(lái)遍歷ReferenceQueue找到里面的key所對(duì)應(yīng)的結(jié)點(diǎn)清除掉
使用場(chǎng)景
- WeakHashMap的鍵是弱引用關(guān)聯(lián)對(duì)象;
- HashMap是強(qiáng)引用關(guān)聯(lián)
到此這篇關(guān)于關(guān)于WeakhashMap與HashMap之間的區(qū)別和聯(lián)系的文章就介紹到這了,更多相關(guān)WeakhashMap與HashMap內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java Servlet簡(jiǎn)單實(shí)例分享(文件上傳下載demo)
下面小編就為大家?guī)?lái)一篇Java Servlet簡(jiǎn)單實(shí)例分享(文件上傳下載demo)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05Java中?SLF4J和Logback和Log4j和Logging的區(qū)別與聯(lián)系
這篇文章主要介紹了Java中?SLF4J和Logback和Log4j和Logging的區(qū)別與聯(lián)系,文章通過(guò)圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考幾種,感興趣的小伙伴可以參考一下2022-09-09Spring Boot集成sa-token的項(xiàng)目實(shí)踐
本文主要介紹了Spring Boot集成sa-token的項(xiàng)目實(shí)踐,實(shí)現(xiàn)了基本的登錄和權(quán)限控制功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-05-05Java8新特性之泛型的目標(biāo)類(lèi)型推斷_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
泛型是Java SE 1.5的新特性,泛型的本質(zhì)是參數(shù)化類(lèi)型,也就是說(shuō)所操作的數(shù)據(jù)類(lèi)型被指定為一個(gè)參數(shù)。下面通過(guò)本文給分享Java8新特性之泛型的目標(biāo)類(lèi)型推斷,感興趣的朋友參考下吧2017-06-06springboot如何使用vue打包過(guò)的頁(yè)面資源
這篇文章主要介紹了springboot如何使用vue打包過(guò)的頁(yè)面資源,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12java.lang.NoSuchMethodException: com.sun.proxy.$Proxy58.list
這篇文章主要介紹了java.lang.NoSuchMethodException: com.sun.proxy.$Proxy58.list錯(cuò)誤解決辦法的相關(guān)資料,需要的朋友可以參考下2016-12-12