在線程中有一種方法,頻繁被大家調用,那就是ThreadLocal。不過在記憶體的處理上,ThreadLocal也會遇到比較棘手的問題,總是會產生一些記憶體的洩漏。這篇文章將會以一個洩漏實例為大家展開分析,也幫助大家了解洩漏中的一些狀況,並提出ThreadLocal對應的解決方案。
1、洩漏實例
ThreadLocalMap的靜態內部類別Entry:
static class Entry extends WeakReference<ThreadLocal<?>> { /** The value associated with this ThreadLocal. */ Object value; Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } }
ThreadLocalMap使用靜態內部類別Entry實作<k,v>存儲,而Entry繼承WeakReference類,所以ThreadLocalMap中的key其實是ThreadLocal的一個弱引用。
正因為ThreadLocalMap以ThreadLocal的微弱引用作為key,在這個ThreadLocal沒有外部強引用的時候,會被GC。這時候,ThreadLocalMap會出現一個key為null的Entry,理所當然的,這個Entry的value將永遠沒辦法被存取。
在這種情況下,如果當前工作線程一直沒有結束,那麼這個key為null的value因為被Entry強引用,而Entry被當前線程的ThreadLocalMap強引用,導致這個value永遠無法被GC,造成內存洩漏。
2、解決辦法
ThreadLocalMap的cleanSomeSlots(),expungeStaleEntry()方法都能清除key為null的value。 在ThreadLocal的set(),get(),remove()方法中,都會呼叫cleanSomeSlots()或expungeStaleEntry()來清除ThreadLocalMap中所有key為null的value。
以上就是java ThreadLocal記憶體洩漏的解決,當然這只能對記憶體洩漏起到一定的作用,畢竟只是一種清楚,不能保證一定不會出現。