【每天一道面試題】說一下ThreadLocal原理及會不會發生內存泄漏

640?wx_fmt=jpeg

ThreadLocal實現原理

ThreadLocal的實現原理是每一個Thread維護一個ThreadLocalMap映射表,映射表的key是ThreadLocal實例,並且使用的是ThreadLocal的弱引用 ,value是具體需要存儲的Object。下面用一張圖展示這些對象之間的引用關係,實心箭頭表示強引用,空心箭頭表示弱引用。

640?wx_fmt=jpeg

內存泄漏問題

從上圖可以看出,如果ThreadLocal沒有外部強引用,當發生垃圾回收時,這個ThreadLocal一定會被回收(弱引用的特點是不管當前內存空間足夠與否,GC時都會被回收),這樣就會導致ThreadLocalMap中出現key爲null的Entry,外部將不能獲取這些key爲null的Entry的value,並且如果當前線程一直存活,那麼就會存在一條強引用鏈:Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value,導致value對應的Object一直無法被回收,產生內存泄露。

查看源碼會發現,ThreadLocal的get、set和remove方法都實現了對所有key爲null的value的清除,但仍可能會發生內存泄露,因爲可能使用了ThreadLocal的get或set方法後發生GC,此後不調用get、set或remove方法,爲null的value就不會被清除。

解決辦法是每次使用完ThreadLocal都調用它的remove()方法清除數據,或者按照JDK建議將ThreadLocal變量定義成private static,這樣就一直存在ThreadLocal的強引用,也就能保證任何時候都能通過ThreadLocal的弱引用訪問到Entry的value值,進而清除掉。

爲了更方便的技術交流,建了一個微信羣,加博主微信wind7rui,邀你進羣!

END 

如果覺得有收穫,記得關注、點贊、轉發。

640?wx_fmt=png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章