亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

WeakHashMap

2019-11-15 00:06:47
字體:
來源:轉載
供稿:網友
WeakHashMap

WeakHashMap,當除了自身有對key的引用外,此key沒有其他引用那么此map會自動丟棄此值。

code

此例子中聲明了兩個Map對象,一個是HashMap,一個是WeakHashMap,同時向兩個map中放入a、b兩個對象,當HashMap.remove掉a 并且將a、b都指向null時,WeakHashMap中的a將自動被回收掉。出現這個狀況的原因是,對于a對象而言,當HashMap.remove掉并且將a指向null后,除了WeakHashMap中還保存a外已經沒有指向a的指針了,所以WeakHashMap會自動舍棄掉a,而對于b對象雖然指向了null,但HashMap中還有指向b的指針,所以WeakHashMap將會保留。

public class Test {      public static void main(String[] args) throws Exception {          String a = new String("a");          String b = new String("b");          Map weakmap = new WeakHashMap();          Map map = new HashMap();          map.put(a, "aaa");          map.put(b, "bbb");                    weakmap.put(a, "aaa");          weakmap.put(b, "bbb");                    map.remove(a);                    a=null;          b=null;                    System.gc();          Iterator i = map.entrySet().iterator();          while (i.hasNext()) {              Map.Entry en = (Map.Entry)i.next();              System.out.我是天王蓋地虎的分割線

WeakHashMap是主要通過expungeStaleEntries這個函數的來實現移除其內部不用的條目從而達到的自動釋放內存的目的的.基本上只要對WeakHashMap的內容進行訪問就會調用這個函數,從而達到清除其內部不在為外部引用的條目。但是如果預先生成了WeakHashMap,而在GC以前又不曾訪問該WeakHashMap,那不是就不能釋放內存了嗎?

public class WeakHashMapTest1 {    public static void main(String[] args) {        List<WeakHashMap<long[][], long[][]>> maps = new ArrayList<WeakHashMap<long[][], long[][]>>();        for (int i = 0; i < 1000000; i++) {            WeakHashMap<long[][], long[][]> d = new WeakHashMap<long[][], long[][]>();            d.put(new long[1000][1000], new long[1000][1000]);            maps.add(d);            System.gc();            System.err.println(i);        }    }}

該測試跑不了幾步循環就內存溢出了。果不其然,WeakHashMap這個時候并沒有自動幫我們釋放不用的內存。

image

public class WeakHashMapTest2 {       public static void main(String[] args) throws Exception {              List<WeakHashMap<long[][], long[][]>> maps = new ArrayList<WeakHashMap<long[][], long[][]>>();              for (int i = 0; i < 1000; i++) {                     WeakHashMap<long[][], long[][]> d = new WeakHashMap<long[][], long[][]>();                     d.put(new long[1000][1000], new long[1000][1000]);                     maps.add(d);                     System.gc();                     System.err.println(i);                     for (int j = 0; j < i; j++) {                            System.err.println(j + " size" + maps.get(j).size());                     }              }       }}

image

這次測試輸出正常,不在出現內存溢出問題??偨Y來說:WeakHashMap并不是你啥也干他就能自動釋放內部不用的對象的,而是在你訪問它的內容的時候釋放內部不用的對象。

WeakHashMap實現弱引用,是因為它的Entry<K,V>是繼承自WeakReference<K>的。在WeakHashMap$Entry<K,V>的類定義及構造函數里面是這樣寫的:

private static class Entry<K,V> extends WeakReference<K> implements Map.Entry<K,V> Entry(K key, V value, ReferenceQueue<K> queue,int hash, Entry<K,V> next) {        super(key, queue);        this.value = value;        this.hash = hash;        this.next = next; }

請注意它構造父類的語句:“super(key, queue);”,傳入的是key,因此key才是進行弱引用的,value是直接強引用關聯在this.value之中。在System.gc()時,key中的byte數組進行了回收,而value依然保持(value被強關聯到entry上,entry又關聯在map中,map關聯在arrayList中)。

如何證明key中的byte被回收了呢?可以通過內存溢出時導出的內存鏡像進行分析,也可以通過如下的小測試得出結論:

for (int i = 0; i < 10000; i++) {        WeakHashMap<long[][], Object> d = new WeakHashMap<long[][], Object>();        d.put(newlong[1000][1000], new Object());        maps.add(d);               System.gc();        System.err.println(i); }

上面的代碼,即使執行10000次也沒有問題,證明key中的long數組確實被回收了。for循環中每次都new一個新的WeakHashMap,在put操作后,雖然GC將WeakReference的key中的long數組回收了,并將事件通知到了ReferenceQueue,但后續卻沒有相應的動作去觸發WeakHashMap 去處理 ReferenceQueue。所以 WeakReference 包裝的key依然存在在WeakHashMap中,其對應的value也當然存在。(就是說long被回收掉了,但是new Object沒有被回收掉)

那value是何時被清除的呢?

對兩個例子進行分析可知,例子二中的maps.get(j).size()觸發了value的回收,那又如何觸發的呢.查看WeakHashMap源碼可知,size方法調用了expungeStaleEntries方法,該方法對vm要回收的的entry(quene中)進行遍歷,并將entry的value置空,回收了內存。所以效果是key在GC的時候被清除,value在key清除后訪問WeakHashMap被清除。

疑問:key的quene與map的quene是同一個quene,poll操作會減少一個reference,那問題是key如果先被清除,expungeStaleEntries遍歷quene時那個被回收的key對應的entry還能取出來么???

關于執行System.GC時,key中的long數據如何被回收了,請見WeakReference referenceQueneWeakHashMap

public class WeakHashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>

以弱鍵實現的基于哈希表的 Map。在 WeakHashMap 中,當某個鍵不再正常使用時,將自動移除其條目。更精確地說,對于一個給定的鍵,其映射的存在并不阻止垃圾回收器對該鍵的丟棄,這就使該鍵成為可終止的,被終止,然后被回收。丟棄某個鍵時,其條目從映射中有效地移除,因此,該類的行為與其他的 Map 實現有所不同。null 值和 null 鍵都被支持。該類具有與 HashMap 類相似的性能特征,并具有相同的效能參數初始容量 和加載因子。

像大多數集合類一樣,該類是不同步的??梢允褂?Collections.synchronizedMap 方法來構造同步的 WeakHashMap。

該類主要與這樣的鍵對象一起使用,其 equals 方法使用 == 運算符來測試對象標識。

一旦這種鍵被丟棄,就永遠無法再創建了,所以,過段時間后在 WeakHashMap 中查找此鍵是不可能的,不必對其項已移除而感到驚訝。該類十分適合與 equals 方法不是基于對象標識的鍵對象一起使用,比如,String 實例。

然而,對于這種可重新創建的鍵對象,鍵若丟棄,就自動移除 WeakHashMap 條目,這種表現令人疑惑。

WeakHashMap 類的行為部分取決于垃圾回收器的動作,所以,幾個常見的(雖然不是必需的)Map 常量不支持此類。

因為垃圾回收器在任何時候都可能丟棄鍵,WeakHashMap 就像是一個被悄悄移除條目的未知線程。特別地,即使對 WeakHashMap 實例進行同步,并且沒有調用任何賦值方法,在一段時間后 ,size 方法也可能返回較小的值,對于 isEmpty 方法,可能返回 false,然后返回 true,對于給定的鍵,containsKey 方法可能返回 true 然后返回 false,對于給定的鍵,get 方法可能返回一個值,但接著返回 null,對于以前出現在映射中的鍵,put 方法返回 null,而 remove 方法返回 false,對于鍵集、值集、項集進行的檢查,生成的元素數量越來越少。

WeakHashMap 中的每個鍵對象間接地存儲為一個弱引用的指示對象。因此,不管是在映射內還是在映射之外,只有在垃圾回收器清除某個鍵的弱引用之后,該鍵才會自動移除。

實現注意事項:WeakHashMap 中的值對象由普通的強引用保持。因此應該小心謹慎,確保值對象不會直接或間接地強引用其自身的鍵,因為這會阻止鍵的丟棄。注意,值對象可以通過 WeakHashMap 本身間接引用其對應的鍵;這就是說,某個值對象可能強引用某個其他的鍵對象,而與該鍵對象相關聯的值對象轉而強引用第一個值對象的鍵。處理此問題的一種方法是,在插入前將值自身包裝在 WeakReferences 中,如:m.put(key, new WeakReference(value)),然后,分別用 get 進行解包。

該類所有“collection 視圖方法”返回的迭代器均是快速失敗的:在迭代器創建之后,如果從結構上對映射進行修改,除非通過迭代器自身的 remove 或 add 方法,其他任何時間任何方式的修改,迭代器都將拋出 ConcurrentModificationException。因此,面對并發的修改,迭代器很快就完全失敗,而不是冒著在將來不確定的時間任意發生不確定行為的風險。注意,迭代器的快速失敗行為不能得到保證,一般來說,存在不同步的并發修改時,不可能作出任何堅決的保證??焖偈〉鞅M最大努力拋出 ConcurrentModificationException。因此,編寫依賴于此異常程序的方式是錯誤的。

正確做法是:迭代器的快速失敗行為應該僅用于檢測 bug。注意1: null 值和 null 鍵都被支持。注意2:不是線程安全的。注意3:迭代器的快速失敗行為不能得到保證。注意4:WeakHashMap是無序的。注意5: 確保值對象不會直接或間接地強引用其自身的鍵,

因為這會阻止鍵的丟棄。但是,值對象可以通過 WeakHashMap 本身間接引用其對應的鍵;這就是說,某個值對象可能強引用某個其他的鍵對象,而與該鍵對象相關聯的值對象轉而強引用第一個值對象的鍵,這時就形成了環路。處理此問題的一種方法是,在插入前將值自身包裝在WeakReferences中,如:m.put(key, new WeakReference(value)),然后,分別用 get 進行解包。

我是天王蓋地虎的分割線
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
69视频在线播放| 蜜臀久久99精品久久久无需会员| 亚洲国产精品一区二区三区| 亚洲精品国产精品自产a区红杏吧| 欧美日韩亚洲高清| 国产精品久久久久久久久久久不卡| 久久综合国产精品台湾中文娱乐网| 国产欧美日韩精品丝袜高跟鞋| 亚洲第一黄色网| 日韩在线视频线视频免费网站| 91国产高清在线| 亚洲加勒比久久88色综合| 国语自产偷拍精品视频偷| 91欧美精品午夜性色福利在线| 成人有码在线视频| 午夜精品在线视频| 欧美日韩国产精品一区二区三区四区| 深夜福利一区二区| 国产日韩av在线| 中文字幕少妇一区二区三区| 久操成人在线视频| 日韩欧美大尺度| 欧美性视频在线| yellow中文字幕久久| 在线观看91久久久久久| 精品欧美一区二区三区| 国产精品美女视频网站| 国语自产精品视频在线看一大j8| 亚洲人永久免费| 欧美一级片久久久久久久| 日韩视频免费观看| 97在线视频观看| 青青草精品毛片| 亚洲午夜未满十八勿入免费观看全集| 久久人人爽亚洲精品天堂| 国产精品女视频| 精品一区精品二区| 伊人一区二区三区久久精品| 国产网站欧美日韩免费精品在线观看| 按摩亚洲人久久| 久热精品视频在线免费观看| 最新日韩中文字幕| 亚洲夜晚福利在线观看| 日韩成人av网址| 亚洲国产精品电影在线观看| 亚洲精美色品网站| 伊人激情综合网| 日韩av在线免播放器| 在线精品国产成人综合| 成人黄色短视频在线观看| 亚洲精品天天看| 茄子视频成人在线| 在线成人免费网站| 欧美洲成人男女午夜视频| 国产美女扒开尿口久久久| 国产在线播放91| 成人a免费视频| 久久这里只有精品99| 国产精品啪视频| 精品国产乱码久久久久久婷婷| 美女性感视频久久久| 欧美电影在线观看高清| 国产精品影院在线观看| 国产精品网站入口| 日韩视频亚洲视频| 91精品国产91久久久久久吃药| 国产欧美最新羞羞视频在线观看| 亚洲一区二区久久久久久| 国产精品久久久久久久美男| 91久久精品国产91久久| 欧美日韩国产一区中文午夜| 色噜噜狠狠狠综合曰曰曰| 亚洲理论电影网| 91av在线网站| 日韩精品福利在线| 欧美日韩国产页| 欧美大胆a视频| 欧美另类交人妖| 欧美精品成人91久久久久久久| 国产精品免费视频xxxx| 色777狠狠综合秋免鲁丝| 在线观看欧美www| 疯狂欧美牲乱大交777| 日韩免费在线观看视频| 精品av在线播放| 8090成年在线看片午夜| **欧美日韩vr在线| 国产精品视频一区国模私拍| 日韩大胆人体377p| 91精品国产精品| 97人洗澡人人免费公开视频碰碰碰| 九九精品在线观看| 国产成人精品久久二区二区91| 日韩在线观看免费| 久久久久北条麻妃免费看| 性色av一区二区咪爱| 亚洲视频免费一区| 97精品久久久中文字幕免费| 亚洲黄页视频免费观看| 亚洲女人被黑人巨大进入al| 欧美在线免费视频| 欧美日韩国产999| 欧美一区二区三区免费视| 中文字幕亚洲欧美| 国产精品18久久久久久首页狼| 神马国产精品影院av| 欧美午夜激情在线| 91精品免费看| 欧美成人精品在线视频| 国产在线精品自拍| 久久久欧美精品| 热久久免费视频精品| 456亚洲影院| 国产精品视频xxx| 欧美激情精品久久久久| 久久视频中文字幕| 亚洲国产欧美日韩精品| 国产视频久久久| 欧美午夜激情小视频| 92看片淫黄大片看国产片| 国产精品va在线播放| 久久偷看各类女兵18女厕嘘嘘| 欧美激情在线观看视频| 国产91久久婷婷一区二区| 亚洲男女性事视频| 国产成人亚洲综合91| 亚洲午夜精品久久久久久久久久久久| 亚洲精品www| 欧美老女人bb| 国产精品免费在线免费| 国产激情综合五月久久| 亚洲系列中文字幕| 日韩国产精品亚洲а∨天堂免| 98视频在线噜噜噜国产| 午夜精品视频在线| 精品久久久久久久久久久久| 欧美日韩加勒比精品一区| 九九热精品视频国产| 欧美亚洲国产成人精品| 久久久久www| 理论片在线不卡免费观看| 国产精品久久久久一区二区| 国内精品模特av私拍在线观看| 久久久精品久久久| 九九视频这里只有精品| 久久久久久久香蕉网| 成人精品一区二区三区电影黑人| 久久韩剧网电视剧| 久久久久久久久久久国产| 日本精品在线视频| 久久久久久久久久久免费精品| 国内精品一区二区三区四区| 精品久久久久久亚洲国产300| 亚洲精品中文字幕有码专区| 亚洲欧洲在线播放| 日韩精品高清在线| 日韩激情视频在线| 亚洲国产精品va| 国产亚洲成精品久久| 久久久久久91香蕉国产| 色在人av网站天堂精品| 精品久久久国产精品999| 精品日韩视频在线观看| 国产精品男女猛烈高潮激情|