WeakHashMap 源碼理解
阿新 • • 發佈:2018-08-02
概念 存在 ash kref dex 清空 adl pre nbsp 。如果沒有有效引用指向該對象(基本意味著不存在訪問該對象的方式),那麽該對象就是可回收的。這裏的“有效引用”並不包括弱引用。也就是說,雖然弱引用可以用來訪問對象,但進行垃圾回收時弱引用並不會被考慮在內,僅有弱引用指向的對象仍然會被GC回收。
WeakHashMap,從名字可以看出它是某種 Map。它的特殊之處在於 WeakHashMap 裏的entry
可能會被GC自動刪除,即使程序員沒有調用remove()
或者clear()
方法。
WeekHashMap 的這個特點特別適用於需要緩存的場景。在緩存場景下,由於內存是有限的,不能緩存所有對象;對象緩存命中可以提高系統效率。
要明白 WeekHashMap 的工作原理,還需要引入一個概念:弱引用(WeakReference)。我們都知道Java中內存是通過GC自動管理的,GC會在程序運行過程中自動判斷哪些對象是可以被回收的,並在合適的時機進行內存釋放。GC判斷某個對象是否可被回收的依據是,是否有有效的引用指向該對象
WeakHashMap 內部是通過弱引用來管理entry
的,弱引用的特性對應到 WeakHashMap 上意味著什麽呢?將一對key, value
放入到 WeakHashMap 裏並不能避免該key
值被GC回收,除非在 WeakHashMap 之外還有對該key
的強引用。
重點:自帶清理功能的Map。
// 清空table中無用鍵值對。原理如下: // (01) 當WeakHashMap中某個“弱引用的key”由於沒有再被引用而被GC收回時, // 被回收的“該弱引用key”也被會被添加到"ReferenceQueue(queue)"中。 // (02) 當我們執行expungeStaleEntries時, // 就遍歷"ReferenceQueue(queue)"中的所有key
// 然後就在“WeakReference的table”中刪除與“ReferenceQueue(queue)中key”對應的鍵值對
/** * Expunges stale entries from the table. */ private void expungeStaleEntries() { Entry<K,V> e; while ( (e = (Entry<K,V>) queue.poll()) != null) { int h = e.hash; int i = indexFor(h, table.length); Entry<K,V> prev = table[i]; Entry<K,V> p = prev; while (p != null) { Entry<K,V> next = p.next; if (p == e) { if (prev == e) table[i] = next; else prev.next = next; e.next = null; // Help GC e.value = null; // " " size--; break; } prev = p; p = next; } } }
我竟然以為weakhashMap 用 線性試探法解決的hash沖突。哈哈。ThreadLocalMap 用這貨解決的hash沖突,記混了!!
WeakHashMap 源碼理解