WeakHashMap垃圾回收原理
簡書 滌生。
轉載請注明原創出處,謝謝!
如果讀完覺得有收獲的話,歡迎點贊加關注。
介紹
WeakHashMap自然聯想到的是HashMap。確實,WeakHashMap與HashMap一樣是個散列表,存儲內容也是鍵值對。與HashMap類似的功能就不展開了,本文重點關注在WeakHashMap是如何做到回收數據?
垃圾回收原理
談WeakHashMap回收原理得從WeakReference(弱引用)說起。大家都知道GC回收對象前提是,從根集出發的引用中沒有有效引用指向該對象,則該對象就可以被回收,這里的有效引用并不包含WeakReference,雖然弱引用可以用來訪問對象,但進行垃圾回收時弱引用并不會被考慮在內,僅有弱引用指向的對象仍然會被GC回收。
那WeakHashMap是如何跟WeakReference關聯起來的呢?
我們一起看看實現的code吧。
大家都知道HashMap實現里面有個Entry數組,WeakHashMap也一樣也有一個Entry數組,但是此Entry與彼Entry有些不一樣。WeakHashMap的Entry是繼承WeakReference,這樣一來,整個Entry就是一個WeakReference,再來看看Entry的構造方法,調用了super(key, queue),也就是調用了這個構造方法
有兩個參數,一個key,一個是queue,這個key就是WeakHashMap中存儲的key值,這個queue是WeakHashMap中創建的ReferenceQueue。
那這個ReferenceQueue是干嘛的呢?了解GC的朋友可能知道,當GC某個對象時,如果有此對象上還有弱引用與其關聯,會將WeakReference對象與Reference類的pending引用關聯起來,然后由Reference Handler線程將該插入ReferenceQueue隊列。
也就是說當Entry中的key被GC時,會將Entry放入到ReferenceQueue中,WeakHashMap就能個通過ReferenceQueue中的Entry了解到哪些key已經被GC,或者即將馬上被GC,起到了通知的作用。
了解了以上信息后,我們再看下面這段代碼:
這段代碼就是WeakHashMap用來處理ReferenceQueue中被GC的key所關聯的Entry相關數據,通過從queue中poll出相關的Entry,然后去WeakHashMap的entry數組中找到索引,然后從對應的鏈中去掉相關的Entry,最后將value賦值為空(Help GC),到這里就完成了相關數據的清理。
但是誰來觸發expungeStaleEntries方法呢?有多個方法都可以觸發,如put、get、remove、size等方法都能夠觸發相關的邏輯。
誤區
是不是使用了WeakHashMap就一定沒有問題了呢?當然不是,如果沒有觸發expungeStaleEntries這個方法依然會導致內存泄漏,比如初始化好WeakHashMap中相關數據后,一直不調用put、get、remove、size等相關方法,也是不能夠正常回收的。
總結
了解了WeakHashMap原理之后,使用起來是不是更加得心應手了呢。
個人微信公共號,感興趣的關注下,獲取更多技術文章