個人對記憶體洩漏的理解:如果乙個我用不到物件一直在記憶體裡,那麼就出現記憶體洩漏了。
簡單說一下theadlocal實現原理:
通過執行緒私有的空間來儲存資料,即在thread類裡有乙個threadlocalmap型別的變數:
/* threadlocal values pertaining to this thread. this map is maintained
* by the threadlocal class. */
threadlocal.threadlocalmap threadlocals = null;
threadlocal.threadlocalmap就是乙個map,內部使用了乙個entry型別的陣列來儲存資料:
static class entry extends weakreference>
}
從原始碼上看,entry是繼承弱引用weakreference的,k對於entry就是乙個弱引用,如果k不存在強引用,那麼它將會被**,此時entry的k是空。
乙個關鍵資訊:entry的k就是乙個threadlocal物件,threadlocal相對於entry來說就是乙個弱引用。
theadlocal物件如果在外部不存在強引用,那麼對應entry的k將會被**掉,有部分文章認為此時如果不呼叫threadlocal#remove()方法,將會出現entry和value不會被**掉,從而出現記憶體洩漏。但我認為此時不一定出現記憶體洩漏的,因為threadloocal有乙個cleansomeslots方法,它會把key==null的entry給**掉。測試:
public static void main(string args) throws exception
system.out.println(getthreadlocalmapsize());
} /** 獲取entry的數量 */
private static int getthreadlocalmapsize() throws exception
執行完成後,主線程的threadlocalmap的entry的size遠遠小於100000。證明threadlocalmap中的無效entry會被自動**。
這種情況也是會有記憶體洩漏的風險,因為cleansomeslots方法依賴於下一次get、set、remove方法呼叫,如果get、set、remove方法再也沒有被呼叫過,那麼此時對應entry也不會被**掉,從而導致記憶體洩漏。
另外一種情況就是申明乙個是全域性的threadlocal變數:
public static final threadlocal threadlocal = new threadlocal();
此時threadlocal就會被所有執行緒所共享,它一直都將會是乙個強引用,導致entry的k一直得不到**從而記憶體洩漏(實際上可能此時我的執行緒已經不需要這個threadlocal了),更好的做法是如果當前執行緒確定不會用到這個threadlocal,就手動調動threadlocal#remove方法,remove方法會將當前執行緒的threadlocalmap中對應entry給**掉。
總結:如果我們能確定我們的執行緒不會再用到threadlocal了,就手動呼叫threadlocal#remove以避免記憶體洩漏!
ThreadLocal記憶體洩漏
重新上傳 取消threadlocal threadlocal的實現是這樣的 每個thread維護乙個threadlocalmap對映表,這個對映表的key是threadlocal例項本身,value是真正需要儲存的object。也就是說threadlocal本身並不儲存值,它只是作為乙個key來讓執...
ThreadLocal 記憶體洩漏
theadlocal 記憶體洩漏的根源是 由於threadlocalmap的生命週期跟thread一樣長,如果沒有手動刪除對應的key就會導致記憶體洩漏,而不是因為弱引用 一 threadlocalmap的 key 為 threadlocal 弱引用 二 threadlocal正確的使用方法 1 每...
ThreadLocal 記憶體洩漏問題
threadlocal 實現原理 threadlocal為什麼會記憶體洩漏 threadlocal 最佳實踐 threadlocal 實現原理 threadlocal的實現是這樣的 每個thread 維護乙個 threadlocalmap 對映表,這個對映表的 key 是 threadlocal例項...