<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-13  評論-22  文章-0  trackbacks-0

    Java WeakHashMap 到底Weak在哪里,它真的很弱嗎?WeakHashMap 的適用場景是什么,使用時需要注意些什么?弱引用和強引用對Java GC有什么不同影響?本文將給出清晰而簡潔的介紹。

    總體介紹

    在Java集合框架系列文章的最后,筆者打算介紹一個特殊的成員:WeakHashMap,從名字可以看出它是某種 Map。它的特殊之處在于 WeakHashMap 里的entry可能會被GC自動刪除,即使程序員沒有調用remove()或者clear()方法。

    更直觀的說,當使用 WeakHashMap 時,即使沒有顯示的添加或刪除任何元素,也可能發生如下情況:

    • 調用兩次size()方法返回不同的值;
    • 兩次調用isEmpty()方法,第一次返回false,第二次返回true
    • 兩次調用containsKey()方法,第一次返回true,第二次返回false,盡管兩次使用的是同一個key
    • 兩次調用get()方法,第一次返回一個value,第二次返回null,盡管兩次使用的是同一個對象。

    遇到這么奇葩的現象,你是不是覺得使用者一定會瘋掉?其實不然,WeekHashMap 的這個特點特別適用于需要緩存的場景。在緩存場景下,由于內存是有限的,不能緩存所有對象;對象緩存命中可以提高系統效率,但緩存MISS也不會造成錯誤,因為可以通過計算重新得到。

    要明白 WeekHashMap 的工作原理,還需要引入一個概念:弱引用(WeakReference)。我們都知道Java中內存是通過GC自動管理的,GC會在程序運行過程中自動判斷哪些對象是可以被回收的,并在合適的時機進行內存釋放。GC判斷某個對象是否可被回收的依據是,是否有有效的引用指向該對象。如果沒有有效引用指向該對象(基本意味著不存在訪問該對象的方式),那么該對象就是可回收的。這里的“有效引用”并不包括弱引用。也就是說,雖然弱引用可以用來訪問對象,但進行垃圾回收時弱引用并不會被考慮在內,僅有弱引用指向的對象仍然會被GC回收

    WeakHashMap 內部是通過弱引用來管理entry的,弱引用的特性對應到 WeakHashMap 上意味著什么呢?將一對key, value放入到 WeakHashMap 里并不能避免該key值被GC回收,除非在 WeakHashMap 之外還有對該key的強引用

    關于強引用,弱引用等概念以后再具體講解,這里只需要知道Java中引用也是分種類的,并且不同種類的引用對GC的影響不同就夠了。

    具體實現

    WeakHashMap的存儲結構類似于HashMap,讀者可自行參考前文,這里不再贅述。

    關于強弱引用的管理方式,博主將會另開專題單獨講解。

    Weak HashSet?

    如果你看過前幾篇關于 MapSet 的講解,一定會問:既然有 WeekHashMap,是否有 WeekHashSet 呢?答案是沒有:( 。不過Java Collections工具類給出了解決方案,Collections.newSetFromMap(Map<E,Boolean> map)方法可以將任何 Map包裝成一個Set。通過如下方式可以快速得到一個 Weak HashSet

    // 將WeakHashMap包裝成一個Set
    Set<Object> weakHashSet = Collections.newSetFromMap(
            new WeakHashMap<Object, Boolean>());

    不出你所料,newSetFromMap()方法只是對傳入的 Map做了簡單包裝:

    // Collections.newSetFromMap()用于將任何Map包裝成一個Set
    public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) {
        return new SetFromMap<>(map);
    }

    private static class SetFromMap<E> extends AbstractSet<E>
        implements Set<E>, Serializable
    {
        private final Map<E, Boolean> m;  // The backing map
        private transient Set<E> s;       // Its keySet
        SetFromMap(Map<E, Boolean> map) {
            if (!map.isEmpty())
                throw new IllegalArgumentException("Map is non-empty");
            m = map;
            s = map.keySet();
        }
        public void clear()               {        m.clear(); }
        public int size()                 { return m.size(); }
        public boolean isEmpty()          { return m.isEmpty(); }
        public boolean contains(Object o) { return m.containsKey(o); }
        public boolean remove(Object o)   { return m.remove(o) != null; }
        public boolean add(E e) { return m.put(e, Boolean.TRUE) == null; }
        public Iterator<E> iterator()     { return s.iterator(); }
        public Object[] toArray()         { return s.toArray(); }
        public <T> T[] toArray(T[] a)     { return s.toArray(a); }
        public String toString()          { return s.toString(); }
        public int hashCode()             { return s.hashCode(); }
        public boolean equals(Object o)   { return o == this || s.equals(o); }
        public boolean containsAll(Collection<?> c) {return s.containsAll(c);}
        public boolean removeAll(Collection<?> c)   {return s.removeAll(c);}
        public boolean retainAll(Collection<?> c)   {return s.retainAll(c);}
        // addAll is the only inherited implementation
        
    }

    結語

    至此深入Java集合框架(Java Collections Framework Internals)系列已經全部講解完畢,希望這幾篇簡短的博文能夠幫助各位讀者對Java容器框架建立基本的理解。通過這里可以返回本系列文章目錄

    如果對各位有哪怕些微的幫助,博主將感到非常高興!如果博文中有任何的紕漏和謬誤,歡迎各位博友指正。

    本文GitHub地址

    posted on 2016-05-31 07:27 CarpenterLee 閱讀(1131) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚洲a在线视频视频| 成人午夜亚洲精品无码网站| 久久青青成人亚洲精品| 一级做a爰片久久毛片免费看| 热99re久久免费视精品频软件| 亚洲黄网站wwwwww| 免费国产黄网站在线观看可以下载| 亚洲精品无码不卡在线播HE| eeuss影院免费92242部| 四虎永久免费影院| 在线91精品亚洲网站精品成人| 波多野结衣中文一区二区免费| 在线观看亚洲网站| 亚洲国产成人久久综合野外| 男性gay黄免费网站| 久久亚洲中文字幕精品一区四| 丁香花在线观看免费观看图片| 亚洲综合色视频在线观看| caoporm超免费公开视频| 亚洲日韩v无码中文字幕| 久久午夜无码免费| 91亚洲精品自在在线观看| 成人免费毛片内射美女APP| 亚洲AV无码一区二区三区网址| 午夜国产羞羞视频免费网站| 一级毛片**免费看试看20分钟| 亚洲中文字幕在线观看| 免费A级毛片无码A∨中文字幕下载| 亚洲人成777在线播放| 日韩一级免费视频| a在线视频免费观看在线视频三区 a毛片成人免费全部播放 | 国产一级一片免费播放| 男人j进女人p免费视频| 九月丁香婷婷亚洲综合色| 91精品免费在线观看| 美女视频黄a视频全免费网站色| 亚洲乱码国产乱码精品精| 中文字幕免费在线看线人 | 亚洲中文久久精品无码| 18禁美女裸体免费网站| 亚洲av无码成人影院一区|