關于WeakhashMap與HashMap之間的區(qū)別和聯(lián)系
Java中四大引用:(強>軟>弱>虛)
- 強引用
//A a是創(chuàng)建一個引用,new A()是開辟一塊地址空間存放引用的對象 , A a = new A(); //a是強引用,只要是強引用,GC(即垃圾回收)就不會回收被引用的對象(即new A())
- 軟引用SoftReference
一般用于實現(xiàn)Java對象的緩存,緩存可有 可無,一般將有用但是非必須的對象用 軟引用關聯(lián),只要是軟引用關聯(lián)的對象,在Java發(fā)生 內(nèi)存溢出 異常之前,會將這些對象列入要 回收的范圍(即內(nèi)存不夠才回收),如果回收之后發(fā)現(xiàn)內(nèi)存還是不夠,才會拋出OOM異常,用軟引用關聯(lián)起來,使用時直接get,就不用每次創(chuàng)建 。例如 假設map頻繁被使用 -》可用 SoftReference關聯(lián) -》 用 SoftReference.get()獲取該對象,以便調(diào)用其方法
- 弱引用 WeakReference
弱引用是用來一些非必須的對象,比軟引用更弱一些,只要是被弱引用關聯(lián)的對象,只能夠生存到下一次垃圾回收之前,一旦發(fā)生垃圾回收,無論當前內(nèi)存是否夠用,都會回收掉被弱引用關聯(lián)的對象
- 虛引用 PhantomReference
別名幽靈引用 最弱的引用關系,一個對象是否具有虛引用的存在,完全是不會對其生命周期產(chǎn)生影響,也無法通過虛引用獲取一個對象的實例,它存在的唯一目的就是在對象被垃圾回收之后收到一個系統(tǒng)通知
特殊的HashMap:WeakHashMap
鍵是弱引用對象,只能存活到下一次垃圾回收之前;
被回收的鍵放在 ReferenceQueue里,在HashMap里,會 根據(jù)ReferenceQueue里的值,把鍵對應的value找到,然后把結(jié)點移除,同時讓當前的value不要引用原先的對象,這些對象才能在下一次垃圾回收時再被回收掉
代碼測試
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) { // //引用隊列 // //將軟引用對象關聯(lián)成一個key值,添加到隊列里,遍歷 隊列中每個元素分別找到其在 HashMap里的位置,然后把結(jié)點(key,value)完全刪除掉 // ReferenceQueue<MyArray> queue = new ReferenceQueue<>(); // //創(chuàng)建一個軟引用對象 // SoftReference<MyArray> softReference = new SoftReference<>(new MyArray(), queue);//當對象被回收時,會直接入到queue里 // //獲取軟引用對象(softReference) // System.out.println(softReference.get()); // //判斷是否被回收(true 被回收 入到隊列) // System.out.println(softReference.isEnqueued()); // // -Xms3M -Xmx5M 即初始給堆3M空間,最大是5M空間 右鍵-》 run configurations——》設置虛擬機參數(shù) // //System.gc();//可模擬垃圾回收 // byte[] array = new byte[3*1024*1024]; // // System.out.println(softReference.get()); // System.out.println(softReference.isEnqueued()); // // 弱引用對象 // 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()); // // //虛引用對象 // ReferenceQueue<Test> queue = new ReferenceQueue<>(); // PhantomReference<Test> phantomReference = new PhantomReference<>(new Test(), queue); // //進程的執(zhí)行,需要線程的支持 // //垃圾回收作為一個線程(等CPU分配時間片)支持虛擬機的執(zhí)行 // //JDK(或虛擬機)里垃圾回收線程是隨機啟動的,調(diào)用 System.gc();可以手動回收 // System.gc(); // if(phantomReference.isEnqueued()){ // System.out.println("該對象已經(jīng)被回收"); // }else{ // System.out.println("該對象已經(jīng)被回收"); // } } }
類的繼承關系
HashMap中的對象可以被拷貝 克隆 序列到磁盤上,WeakhashMap都不行
重要方法
- WeakhashMap的put方法(key重復,新值覆蓋舊值;頭插新節(jié)點)
- 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)會自動new一個 NULLKEY,HashMap的key和value都可以為null;
- WeakhashMap中的put/get/remove/resize等方法均會使用expungeStaleEntries()方法,用來遍歷ReferenceQueue找到里面的key所對應的結(jié)點清除掉
使用場景
- WeakHashMap的鍵是弱引用關聯(lián)對象;
- HashMap是強引用關聯(lián)
到此這篇關于關于WeakhashMap與HashMap之間的區(qū)別和聯(lián)系的文章就介紹到這了,更多相關WeakhashMap與HashMap內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java Servlet簡單實例分享(文件上傳下載demo)
下面小編就為大家?guī)硪黄狫ava Servlet簡單實例分享(文件上傳下載demo)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05Java中?SLF4J和Logback和Log4j和Logging的區(qū)別與聯(lián)系
這篇文章主要介紹了Java中?SLF4J和Logback和Log4j和Logging的區(qū)別與聯(lián)系,文章通過圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考幾種,感興趣的小伙伴可以參考一下2022-09-09Java8新特性之泛型的目標類型推斷_動力節(jié)點Java學院整理
泛型是Java SE 1.5的新特性,泛型的本質(zhì)是參數(shù)化類型,也就是說所操作的數(shù)據(jù)類型被指定為一個參數(shù)。下面通過本文給分享Java8新特性之泛型的目標類型推斷,感興趣的朋友參考下吧2017-06-06java.lang.NoSuchMethodException: com.sun.proxy.$Proxy58.list
這篇文章主要介紹了java.lang.NoSuchMethodException: com.sun.proxy.$Proxy58.list錯誤解決辦法的相關資料,需要的朋友可以參考下2016-12-12