ThreadLocal可能引起的內(nèi)存泄露

原地址

threadlocal里面使用了一個存在弱引用的map,當釋放掉threadlocal的強引用以后,map里面的value卻沒有被回收.而這塊value永遠不會被訪問到了. 所以存在著內(nèi)存泄露.
** 最好的做法是將調(diào)用threadlocal的remove方法.**: 把當前ThreadLocal從當前線程的ThreadLocalMap中移除慨代。(包括key俄占,value)

/**
 * Remove the entry for key.
 */
private void remove(ThreadLocal<?> key) {
    Entry[] tab = table;
    int len = tab.length;
    int i = key.threadLocalHashCode & (len-1);
    for (Entry e = tab[i];
         e != null;
         e = tab[i = nextIndex(i, len)]) {
        if (e.get() == key) {
            e.clear();// 將entry的對threadlocal的引用賦值為null
            expungeStaleEntry(i);//將 entry的value賦值為null
            return;
        }
    }
}

在threadlocal的生命周期中,都存在這些引用. 看下圖: 實線代表強引用,虛線代表弱引用


圖中荣病,ThreadLocalMap維護一個Entry的數(shù)組,所以一個線程可以有過個ThreadLocal實例开仰。

每個thread中都存在一個map(ThreadLocalMap), map的類型是ThreadLocal.ThreadLocalMap. Map中的key為一個threadlocal實例. 這個Map的確使用了弱引用,不過弱引用只是針對key. 每個key都弱引用指向threadlocal. 當把threadlocal實例置為null以后,沒有任何強引用指向threadlocal實例,所以threadlocal將會被gc回收. 但是,我們的value卻不能回收,因為存在一條從current thread連接過來的強引用. 只有當前thread結(jié)束以后, current thread就不會存在棧中,強引用斷開, Current Thread, Map, value將全部被GC回收.

內(nèi)存泄漏的情況

所以得出一個結(jié)論就是只要這個線程對象被gc回收,就不會出現(xiàn)內(nèi)存泄露熬甫,但在threadLocal設(shè)為null和線程結(jié)束這段時間不會被回收的唉锌,就發(fā)生了我們認為的內(nèi)存泄露。其實這是一個對概念理解的不一致警儒,也沒什么好爭論的训裆。最要命的是線程對象不被回收的情況,這就發(fā)生了真正意義上的內(nèi)存泄露蜀铲。比如使用線程池的時候边琉,線程結(jié)束是不會銷毀的,會再次使用的记劝。就可能出現(xiàn)內(nèi)存泄露.

PS

Java為了最小化減少內(nèi)存泄露的可能性和影響变姨,在ThreadLocal的get,set的時候都會清除線程Map里所有key為null的value(get 方法會在遍歷的時候如果遇到key為null,就調(diào)用expungeStaleEntry方法擦除厌丑,set方法在遍歷的時候定欧,如果遇到key為null,就調(diào)用replaceStaleEntry方法替換掉怒竿。見下面代碼)砍鸠。

所以最怕的情況就是,threadLocal對象設(shè)null了愧口,開始發(fā)生“內(nèi)存泄露”睦番,然后使用線程池,這個線程結(jié)束耍属,線程放回線程池中不銷毀托嚣,這個線程一直不被使用,或者分配使用了又不再調(diào)用get,set方法厚骗,那么這個期間就會發(fā)生真正的內(nèi)存泄露示启。

java.lang.ThreadLocal.ThreadLocalMap#set

for (Entry e = tab[i];
e != null;
e = tab[i = nextIndex(i, len)]) {
ThreadLocal<?> k = e.get();

if (k == key) {
e.value = value;
return;
}

// 注意這里
if (k == null) {
replaceStaleEntry(key, value, i);
return;
}
}

java.lang.ThreadLocal.ThreadLocalMap#getEntry--->getEntryAfterMiss

while (e != null) {
    ThreadLocal<?> k = e.get();
    if (k == key)
        return e;
    //注意這里
    if (k == null)
        expungeStaleEntry(i);
    else
        i = nextIndex(i, len);
    e = tab[i];
}
return null;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市领舰,隨后出現(xiàn)的幾起案子夫嗓,更是在濱河造成了極大的恐慌迟螺,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舍咖,死亡現(xiàn)場離奇詭異矩父,居然都是意外死亡,警方通過查閱死者的電腦和手機排霉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門窍株,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人攻柠,你說我怎么就攤上這事球订。” “怎么了瑰钮?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵冒滩,是天一觀的道長。 經(jīng)常有香客問我浪谴,道長开睡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任较店,我火速辦了婚禮士八,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘梁呈。我一直安慰自己婚度,他們只是感情好,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布官卡。 她就那樣靜靜地躺著蝗茁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪寻咒。 梳的紋絲不亂的頭發(fā)上哮翘,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天,我揣著相機與錄音毛秘,去河邊找鬼饭寺。 笑死,一個胖子當著我的面吹牛叫挟,可吹牛的內(nèi)容都是我干的艰匙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼抹恳,長吁一口氣:“原來是場噩夢啊……” “哼员凝!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起奋献,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤健霹,失蹤者是張志新(化名)和其女友劉穎旺上,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體糖埋,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡宣吱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了阶捆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凌节。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖洒试,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情朴上,我是刑警寧澤垒棋,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站痪宰,受9級特大地震影響叼架,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜衣撬,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一乖订、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧具练,春花似錦乍构、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至陵究,卻和暖如春眠饮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背铜邮。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工仪召, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人松蒜。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓扔茅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親牍鞠。 傳聞我的和親對象是個殘疾皇子咖摹,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容