在 get操作遇到key為null時,則expungeStaleEntry進行探測清理,知道探測到null結束,返回探測的結束位置。我們先講下探測式清理,也就是expungeStaleEntry方法,遍歷散列數組,從開始位置向后探測清理過期數據,將過期數據的Entry設置為null,沿途中碰到未過期的數據則將此數據rehash后重新在table數組中定位,如果定位的位置已經有了數據,則會將未過期的數據放到最靠近此位置的Entry=null的桶中,使rehash后的Entry數據距離正確的桶的位置更近一些。expungeStaleEntry在清理元素后,會重新規划沖突的元素。
探測式清理是以當前Entry 往后清理,遇到值為null則結束清理,屬於線性探測清理。
在set操作中以及replaceStaleEntry的方法中都會調用cleanSomeSlots,進行啟發式清理
調用cleanSomeSlots()做一次啟發式清理工作,清理散列數組中Entry的key過期的數據。而啟發式清理被作者定義為:Heuristically scan some cells looking for stale entries.
在cleanSomeSlots內部會選擇不同的位置為起點,輪訓調用expungeStaleEntry進行向后探測清理
在set操作發現table[i]不為空時,並且發現了臟entry,調用 replaceStaleEntry 方法,內部會調用cleanSomeSlots清理臟entry。並且由於expungeStaleEntry會涉及rehash方法,效率較低,為了減少該次數,會進行先前和先后搜搜,確定線性探測的位置
一篇文章,從源碼深入詳解ThreadLocal內存泄漏問題:https://juejin.cn/post/6844903602436358157#heading-2
深入分析 ThreadLocal 內存泄漏問題:https://www.jianshu.com/p/1342a879f523
面試官:小伙子,聽說你看過ThreadLocal源碼?(萬字圖文深度解析ThreadLocal):https://segmentfault.com/a/1190000022663697