相信很多人對weakhashmap並沒有完全理解。
weakhashmap 持有的弱引用的 key。
1. 弱引用的概念:
弱引用是用來描述非必需物件的,被弱引用關聯的物件只能生存到下一次垃圾收集發生之前,當垃圾收集器工作時,無論當前記憶體是否足夠,都會**掉只被弱引用關聯的物件。
2. weakhashmap中的弱引用
key是如何被清除的?
weakhashmap中的清除key的核心方法:
privatevoid
expungestaleentries()
prev =p;
p =next;}}
}
檢視呼叫關係,可以看到幾乎所有的方法都直接或間接的呼叫了該方法。但是檢視weakhashmap原始碼,並沒有找到何時將entry放入queue中。
那麼queue佇列中的entry是如何來的?
key弱引用是如何關聯的?
毫無疑問,一定是在put元素的時候,key被設定為弱引用。
publicv put(k key, v value)
}modcount++;
entry
e =tab[i];
tab[i]
= new entry(k, value, queue, h, e); //建立乙個新節點
if (++size >=threshold)
resize(tab.length * 2);
return
null
; }
其中的queue為:
/*** reference queue for cleared weakentries
*/private
final referencequeuequeue = new referencequeue();
再來看一下entry的宣告及建構函式:
privatestatic
class entryextends weakreferenceimplements map.entry
}
entry繼承了weakreference,並且在建構函式中將key 和 queue 提交給weakreference,那麼再來看一下weakreference的建構函式:
publicclass weakreferenceextends reference
}
public abstract class reference}
現在答案就在reference中。
開啟reference原始碼,可以看到乙個靜態塊:
static
其中for迴圈直到 獲取到 jvm 執行緒組,使用jvm執行緒執行referencehandler。
referencehandler是reference的內部類:
privatestatic
class referencehandler extends
thread
public
void
run()
else
catch
(interruptedexception x)
continue
; }
}//fast path for cleaners
if (r instanceof
cleaner)
referencequeue q =r.queue;
if (q !=referencequeue.null) q.enqueue(r);}}
}
現在我們應該已經清楚了,守護執行緒一直執行入隊操作,將key關聯的entry放入queue中。
但是將key放入queue中需要前提條件: pending
這個pending是在垃圾**的時候,jvm計算物件key的可達性後,發現沒有該key物件的引用,那麼就會把該物件關聯的entry新增到pending中,
所以每次垃圾**時發現弱引用物件沒有被引用時,就會將該物件放入待清除佇列中,最後由應用程式來完成清除,weakhashmap中就負責由
方法expungestaleentries()來完成清除。
例子:
@testpublic
void
weakhashmap()
catch
(interruptedexception e)
system.out.println(weak.size());
}
上面的例子是可以正確的,但是下面的就有問題了:
@testpublic
void
weakhashmap()
catch
(interruptedexception e)
system.out.println(weak.size());
}
無論sleep多長時間,引用也不會被清除。這涉及到string在jvm中的工作方式了,這個問題留給讀者自己思考。
弱弱的戰壕
描述 永恆和mx正在玩乙個即時戰略遊戲,名字嘛 恕本人記性不好,忘了 b。mx在他的基地附近建立了n個戰壕,每個戰壕都是乙個獨立的作戰單位,射程可以達到無限 mx不贏定了?永恆fting.但是,戰壕有乙個弱點,就是只能攻擊它的左下方,說白了就是橫縱座標都不大於它的點 mx 我的戰壕為什麼這麼菜 to...
C 中的弱引用
了解弱引用之前,先了解一下什麼是強引用 例如 object obj new object 就是乙個強引用,記憶體分配乙份空間給用以儲存object資料,這塊記憶體有乙個首位址,也就是obj所儲存的資料,記憶體分配的空間中不僅僅儲存著object物件資訊,還儲存著自己 object本身 被引用的次數。...
C 中的弱引用
了解弱引用之前,先了解一下什麼是強引用 例如 object obj new object 就是乙個強引用,記憶體分配乙份空間給用以儲存object資料,這塊記憶體有乙個首位址,也就是obj所儲存的資料,記憶體分配的空間中不僅僅儲存著object物件資訊,還儲存著自己 object本身 被引用的次數。...