java數據結構之WeakHashMap
阿新 • • 發佈:2019-05-14
== must hash 回收 clas iter 父類 構造 help
一、JAVA中的四種引用類型
1、強引用(StrongReference):強引用是最為普遍的一種引用,如果對象被強引用,那麽垃圾回收器無論如何都不會回收它,當內存不足時會拋出OutOfMemoryError異常。
2、軟引用(SoftReference):如果一個對象只被軟引用,當內存空間足夠時,垃圾回收器就不會回收它。當內存空間不足時,該對象就會被回收。
3、弱引用(WeakReference):如果一個對象只被弱引用,觸發GC時,不管內存是否足夠,垃圾回收器都會將其回收。
4、虛引用(PhantomReference):如果一個對象只有虛引用在引用它,垃圾回收器是可以在任意時候對其進行回收的,虛引用主要用來跟蹤對象被垃圾回收器回收的活動。
二、WeakHashMap源碼分析
由於WeakHashMap的源碼和HashMap差不多,所以只說一些特別的地方。
1、WeakHashMap對於鍵值對的引用類型為弱引用,WeakHashMap定義了一個ReferenceQueue來儲存已經被回收了的鍵值對,當我們需要獲取某個鍵值對的時候會先利用ReferenceQueue將WeakHashMap中已經被回收的鍵值對清除掉。
/** * 用來存儲已經被GC的entry */ private final ReferenceQueue<Object> queue = newReferenceQueue<>(); /** * 從表中刪除陳舊的條目,通過和ReferenceQueue中進行對比,來進行刪除 */ private void expungeStaleEntries() { for (Object x; (x = queue.poll()) != null; ) { synchronized (queue) { @SuppressWarnings("unchecked") Entry<K,V> e = (Entry<K,V>) x; int i = indexFor(e.hash, 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; // Must not null out e.next; // stale entries may be in use by a HashIterator e.value = null; // Help GC size--; break; } prev = p; p = next; } } } }
...
private Entry<K,V>[] getTable() { expungeStaleEntries(); return table; } public int size() { if (size == 0) return 0; expungeStaleEntries(); return size; } public boolean isEmpty() { return size() == 0; } public V get(Object key) { Object k = maskNull(key); int h = hash(k); Entry<K,V>[] tab = getTable(); int index = indexFor(h, tab.length); Entry<K,V> e = tab[index]; while (e != null) { if (e.hash == h && eq(k, e.get())) return e.value; e = e.next; } return null; }
2、WeakHashMap的Entry類繼承了WeakReference類,其構造函數中有一個參數queue用來傳入父類構造函數中,ReferenceQueue用來保存被GC的Entry。
Entry(Object key, V value, ReferenceQueue<Object> queue, int hash, Entry<K,V> next)
3、WeakHashMap的初始化默認參數和HashMap相同,但是其hash方法以及resize方法不同。擴容的時候容量也是將容量變為原來的兩倍
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); } /** * 確定entry的下標位置 */ private static int indexFor(int h, int length) { return h & (length-1); }
java數據結構之WeakHashMap