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

