天天看點

ThreadLocal原理及記憶體洩漏分析

使用ThreadLocal時需注意,一定要及時調用remove()方法清楚ThreadLocal,否則會發送記憶體洩漏,最終導緻記憶體溢出

ThreadLocal的原理:每個Thread類有個ThreadLocalMap,而ThreadLocal本身并不存儲資料,使用ThreadLocalMap來存儲(相當于Map的功能,隻不過它存儲用的Entry節點而不是Entry連結清單),這個ThreadLocalMap的key是ThreadLocal對象本身,value就是要存儲的value。

ThreadLocal記憶體洩漏的原因:基于上面的原理,分析下記憶體洩漏的原因。因為ThreadLocalMap的生命周期和目前線程Thread是一樣的(通過源碼可知: t. threadLocals = new ThreadLocalMap( this , firstValue);),而ThreadLocalMap的key是ThreadLocal,他們之間弱引用(見源碼: static class Entry extends WeakReference<ThreadLocal> { ),是以當ThreadLocal被回收的時候,ThreadLocalMap的key就為null了,對應的value找不到了,導緻了記憶體洩漏。jdk也有些保障措施,在我們調用set()、get()的時候,會清楚key為null的資料,但是這樣被動清楚也不能完全避免記憶體洩漏。

擴充:為什麼用弱引用而不用強引用,其實這也是jdk的保障措施,因為如果是強引用,那麼ThreadLocal也不能被回收,會造成更大的記憶體浪費。