ThreadLocal實現原理
ThreadLocal的實現原理是每一個Thread維護一個ThreadLocalMap映射表,映射表的key是ThreadLocal實例,並且使用的是ThreadLocal的弱引用 ,value是具體需要存儲的Object。下面用一張圖展示這些對象之間的引用關係,實心箭頭表示強引用,空心箭頭表示弱引用。
內存泄漏問題
從上圖可以看出,如果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
如果覺得有收穫,記得關注、點贊、轉發。