介紹
每個線程內部都有一個私有的 ThreadLocalMap
實例,用于存儲該線程關聯的所有 ThreadLocal 變量。 ThreadLocalMap
內部的 Entry
繼承自 WeakReference<ThreadLocal<?>>
。所以**Entry
的 key
(即 ThreadLocal 對象本身)是通過弱引用指向的**。
Entry 中的 value 字段始終保持著對實際存儲值的強引用。
內存泄漏問題分析
當一個 ThreadLocal 對象(也就是key
)在應用程序中不再被任何強引用指向時(例如,聲明它的類實例被回收,或者局部變量超出作用域),在下一次垃圾回收(GC)時,這個弱引用 會被回收此即GC 會回收這個 ThreadLocal
對象,Entry
中的 key
會變為 null
。但是value被 Entry
強引用著,只要線程不死,當前線程ThreadLocalMap的Entry一直強引用者value。假設是長期存活的線程池中的線程,這種泄漏可能會不斷累積,最終可能導致 OutOfMemoryError
。
防止內存泄漏方法:
- 在使用完畢后調用
ThreadLocal.remove()
,remove()
放在finally
塊中執行,確保無論代碼邏輯是否發生異常都能清理資源。 - 將 ThreadLocal 定義為
private static final
,這本身不會導致泄漏(ThreadLocal因為強引用在類上),用完之后必須主動remove