ThreadLocal原理及內(nèi)存泄露以及最佳實(shí)踐

Thread.currentThread.map當(dāng)前線程的map
map的key是ThreadLocal的實(shí)例
當(dāng)ThreadLocal被回收時(shí),其key為null,但value可能泄露與內(nèi)存所以采用弱引用

ThreadLocal的map的Entry為什么采用弱引用

防止內(nèi)存泄漏,tl本身為null時(shí),無(wú)法及時(shí)回收key為null的value
key 使用弱引用:引用的ThreadLocal的對(duì)象被回收了,由于ThreadLocalMap持有ThreadLocal的弱引用,即使沒(méi)有手動(dòng)刪除,ThreadLocal也會(huì)被回收。value在下一次ThreadLocalMap調(diào)用set,get,remove的時(shí)候會(huì)被清除

ThreadLocal用途
聲明式識(shí)事務(wù)

ThreadLocal原理
每個(gè)Thread 維護(hù)一個(gè) ThreadLocalMap 映射表,這個(gè)映射表的 key 是 ThreadLocal實(shí)例本身,value 是真正需要存儲(chǔ)的 Object
ThreadLocal 本身并不存儲(chǔ)值,它只是作為一個(gè) key 來(lái)讓線程從 ThreadLocalMap 獲取 value
ThreadLocalMap 是使用 ThreadLocal 的弱引用作為 Key 的,弱引用的對(duì)象在 GC 時(shí)會(huì)被回收

ThreadLocal導(dǎo)致內(nèi)存泄露

ThreadLocalMap的生命周期跟Thread一樣長(zhǎng)

ThreadLocalMap使用ThreadLocal的弱引用作為key,
如果一個(gè)ThreadLocal沒(méi)有外部強(qiáng)引用來(lái)引用它,那么系統(tǒng) GC 的時(shí)候,
這個(gè)ThreadLocal勢(shì)必會(huì)被回收,這樣一來(lái),ThreadLocalMap中就會(huì)出現(xiàn)key為null的
Entry,就沒(méi)有辦法訪問(wèn)這些key為null的Entry的value,如果當(dāng)前線程再遲遲不結(jié)束的話(線程池重用線程),
這些key為null的Entry的value就會(huì)一直存在一條強(qiáng)引用鏈:
Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value永遠(yuǎn)無(wú)法回收,
造成內(nèi)存泄漏。

ThreadLocal的措施
    get(),set(),remove()的時(shí)候都會(huì)清除線程ThreadLocalMap里所有key為null的value
    但無(wú)法保證 
    
        static的ThreadLocal,延長(zhǎng)了ThreadLocal的生命周期,可能導(dǎo)致的內(nèi)存泄漏
        分配使用了ThreadLocal又不再調(diào)用get(),set(),remove()方法,那么就會(huì)導(dǎo)致內(nèi)存泄漏

ThreadLocal最佳實(shí)踐
每次使用完ThreadLocal,都調(diào)用它的remove()方法,清除數(shù)據(jù)
在使用線程池的情況下,沒(méi)有及時(shí)清理ThreadLocal,不僅是內(nèi)存泄漏的問(wèn)題,更嚴(yán)重的是可能導(dǎo)致業(yè)務(wù)邏輯出現(xiàn)問(wèn)題。所以,使用ThreadLocal就跟加鎖完要解鎖一樣,用完就清理

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容