通過每個執行緒維護一張threadlocalmap
雜湊對映表,key為threadlocal
的弱引用,value是object本身。也就是說,threadlocal本身不存任何實際值,而是通過本身作為key,從threadlocalmap
中獲取具體的值。
實際上,threadlocalmap
儲存的是entry
(這個是底層**實現,每個執行緒持有)的乙個陣列,通過threadlocal
的hashcode&(len-1)
獲取陣列的游標i
,具體如下
private
void
set(threadlocal key, object value)
if (k == null)
}tab[i] = new entry(key, value);
int sz = ++size;
if (!cleansomeslots(i, sz) && sz >= threshold)
rehash();
}
由於entry
使用弱引用關聯threadlocal
物件,而執行緒堆疊內的是使用強引用關聯threadlocal
物件,當執行緒堆疊中的引用釋放,遇到下次gc,threadlocal
將被釋放,也就是說,entry的key將變成null,但此時實際的object還是沒有被釋放,一直在堆記憶體裡面,如果該執行緒一直沒結束,那這塊記憶體就將一直不能被**。
解決在threadlocal設計中,方法get(),set(),remove()的時候都會清除執行緒threadlocalmap裡所有key為null的value。
但是還是無法完全保證記憶體洩漏問題,例如threadlocal宣告稱類成員靜態變數,也就是說threadlocal的引用分配在了方法區,這種導致強引用一直會存放在類方法區,無法**threadlocal例項,這種情況可能會導致記憶體洩漏,具體可以參見threadlocal記憶體洩漏例項
threadmap為什麼要用弱引用
為什麼使用弱引用而不是強引用?
to help deal with very large and long-lived usages, the hash table entries use weakreferences for keys.(官網)
因此,threadlocal記憶體洩漏的根源是:由於threadlocalmap的生命週期跟thread一樣長,如果沒有手動刪除對應key就會導致記憶體洩漏,而不是因為弱引用。
每次使用完threadlocal,都呼叫它的remove()方法,清除資料。
參考:
ThreadLocal深入理解
threadlocal從字面上理解,很容易會把threadlocal誤解為乙個執行緒的本地變數。threadlocal並不是代表當前執行緒,threadlocal其實是採用雜湊表的方式來為每個執行緒都提供乙個變數的副本。從而保證各個執行緒間資料安全。每個執行緒的資料不會被另外執行緒訪問和破壞。每個執...
深入理解ThreadLocal
threadlocal例項為每乙個訪問它的執行緒 即當前執行緒 都關聯了乙個該執行緒的執行緒特有物件 執行緒特有物件 tso,thread specific object 各個執行緒建立各自的例項,乙個例項只能被乙個執行緒訪問的物件就被稱為執行緒特有物件,相對應的執行緒就被稱為該執行緒特有物件的持有...
深入理解threadlocal
threadlocal,很多地方叫做執行緒本地變數,也有些地方叫做執行緒本地儲存,其實意思差不多。可能很多朋友都知道threadlocal為變數在每個執行緒中都建立了乙個副本,那麼每個執行緒可以訪問自己內部的副本變數。這句話從字面上看起來很容易理解,但是真正理解並不是那麼容易。我們還是先來看乙個例子...