1. 程式人生 > >weakHashMap解析

weakHashMap解析

weakHashMap

包路徑:package java.util;

               import java.lang.ref.WeakReference;

               import java.lang.ref.ReferenceQueue;

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

1、繼承於AbstractMap,實現了Map介面。

2、weakHashMap是雜湊表,但是它的鍵是“弱鍵”,weakHashMap中保護幾個重要的成員變數:

    table是一個Entry[ ]型別的陣列,而Entry是一個單向連結串列,雜湊表中的鍵值對都是儲存在Entry陣列中的。

   size是表示儲存的鍵值對的數量大小。

   threshold是閾值,用於判斷是否需要擴充容量。

   loadFactor是載入因子。

  modCount是用來實現fail-fast機制的。

  queue儲存的是“已被GC清除的”“弱引用的鍵”。

3、該集合類的主要特點是:

隨著時間的推移,鍵值對會逐漸的減少----->GC 垃圾回收

基本原理:weakHashMap的特點是:當除了自身有對key的引用之外,此key沒有其他的引用,那麼weakHashMap會在下一次對weakHashMap進行增刪改查操作的時候及時丟棄該鍵值對,節約記憶體的使用,此特性使得weakHashMap比較適合構建快取系統。

weakHashMap主要是通過expungeStaleEntries函式來實現移除內部不用的Entry從而達到自動釋放內部的目的。

 private void expungeStaleEntries() { 
        for (Object x; (x = queue.poll()) != null; ) { 
      通過迴圈一直從queue中取出過期的entry,直至取完為止
            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) {
在同步程式碼塊中先把queue中取出的Object型別的資料強制轉化為Entry物件e,然後計算此entry在桶中的位置,然後開始遍歷entry連結串列,如果此entry是連結串列頭,設定此entry的後繼為新的連結串列頭
                        if (prev == e)
                            table[i] = next;
                        else
        然後將此entry的前序節點的後繼指標指向此entry的後繼節點
                            prev.next = next;
        設定被刪除的entry的value為null,加速垃圾回收,相應的size--
                            e.value = null; // Help GC
                            size--;
                            break;
                    }
                    prev = p;
                    p = next;
                }
            

4、弱鍵的原理------>大致是通過WeakReference和ReferenceQueue來實現的。

實現步驟:(1)建立weakHashMap的時候,將鍵值對存放到陣列連結串列當中;(2)當發生GC時會判斷key是否有物件引用,如果沒有引用了,就回收該key,意味著我們的entry實體從我們的集合中回收,回收的同時,將該物件加入到ReferenceQueue中;(3)在操作weakHashMap的時候,會首先同步table和Queue,table存放的是所有有效的鍵值對,Queue存放的是被回收的鍵值對,在table中刪除Queue中有的鍵值對。

5、關於Java中的4種引用

(WeakHashMap中使用WeakReference,也就是通過虛引用來實現的)

(1)強引用(Strong Reference)--->永遠不會回收被引用的物件,比如程式碼中new出來的物件

(2)軟引用(SoftReference)--->表示有用但是非必需的,如果系統記憶體資源緊張,可能就會被回收

(3)弱引用(WeakReference)--->表示非必需的物件,只能存活到下一次垃圾回收發生之前

(4)虛引用(PhantomReference)--->是最弱的,該引用無法操作物件

6、哪些方法會產生清理元素的操作?

put、get方法開始的getTable會呼叫一次expungeStaleEntries

resize方法開始的getTable會呼叫一次expungeStaleEntries

transfer方法本身會判斷弱引用指向的物件是否已經被GC

擴容之後發現size小於閾值的一半,會呼叫一次expungeStaleEntries

size方法會呼叫expungeStaleEntries