<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    狂奔 lion

    自強(qiáng)不息

    關(guān)于ThreadLocal的內(nèi)存泄露

    ThreadLocal是一種confinement,confinement和local及immutable都是線程安全的(如果JVM可信的話)。因?yàn)閷?duì)每個(gè)線程和value之間存在hash表,而線程數(shù)量未知,從表象來看ThreadLocal會(huì)存在內(nèi)存泄露,讀了代碼,發(fā)現(xiàn)實(shí)際上也可能會(huì)內(nèi)存泄露。

    事實(shí)上每個(gè)Thread實(shí)例都具備一個(gè)ThreadLocal的map,以ThreadLocal Instance為key,以綁定的Object為Value。而這個(gè)map不是普通的map,它是在ThreadLocal中定義的,它和普通map的最大區(qū)別就是它的Entry是針對(duì)ThreadLocal弱引用的,即當(dāng)外部ThreadLocal引用為空時(shí),map就可以把ThreadLocal交給GC回收,從而得到一個(gè)null的key。

    這個(gè)threadlocal內(nèi)部的map在Thread實(shí)例內(nèi)部維護(hù)了ThreadLocal Instance和bind value之間的關(guān)系,這個(gè)map有threshold,當(dāng)超過threshold時(shí),map會(huì)首先檢查內(nèi)部的ThreadLocal(前文說過,map是弱引用可以釋放)是否為null,如果存在null,那么釋放引用給gc,這樣保留了位置給新的線程。如果不存在slate threadlocal,那么double threshold。除此之外,還有兩個(gè)機(jī)會(huì)釋放掉已經(jīng)廢棄的threadlocal占用的內(nèi)存,一是當(dāng)hash算法得到的table index剛好是一個(gè)null key的threadlocal時(shí),直接用新的threadlocal替換掉已經(jīng)廢棄的。另外每次在map中新建一個(gè)entry時(shí)(即沒有和用過的或未清理的entry命中時(shí)),會(huì)調(diào)用cleanSomeSlots來遍歷清理空間。此外,當(dāng)Thread本身銷毀時(shí),這個(gè)map也一定被銷毀了(map在Thread之內(nèi)),這樣內(nèi)部所有綁定到該線程的ThreadLocal的Object Value因?yàn)闆]有引用繼續(xù)保持,所以被銷毀。

    從上可以看出Java已經(jīng)充分考慮了時(shí)間和空間的權(quán)衡,但是因?yàn)橹脼閚ull的threadlocal對(duì)應(yīng)的Object Value無法及時(shí)回收。map只有到達(dá)threshold時(shí)或添加entry時(shí)才做檢查,不似gc是定時(shí)檢查,不過我們可以手工輪詢檢查,顯式調(diào)用map的remove方法,及時(shí)的清理廢棄的threadlocal內(nèi)存。需要說明的是,只要不往不用的threadlocal中放入大量數(shù)據(jù),問題不大,畢竟還有回收的機(jī)制。

    綜上,廢棄threadlocal占用的內(nèi)存會(huì)在3中情況下清理:
    1 thread結(jié)束,那么與之相關(guān)的threadlocal value會(huì)被清理
    2 GC后,thread.threadlocals(map) threshold超過最大值時(shí),會(huì)清理
    3 GC后,thread.threadlocals(map) 添加新的Entry時(shí),hash算法沒有命中既有Entry時(shí),會(huì)清理

    那么何時(shí)會(huì)“內(nèi)存泄露”?當(dāng)Thread長(zhǎng)時(shí)間不結(jié)束,存在大量廢棄的ThreadLocal,而又不再添加新的ThreadLocal(或新添加的ThreadLocal恰好和一個(gè)廢棄ThreadLocal在map中命中)時(shí)。

     @2008 楊一. 版權(quán)所有. 保留所有權(quán)利

    posted on 2010-07-02 18:27 楊一 閱讀(2284) 評(píng)論(2)  編輯  收藏 所屬分類: Java SE 、Other Tech

    評(píng)論

    # re: 關(guān)于ThreadLocal的內(nèi)存泄露[未登錄] 2010-07-03 09:32 m

    他的目的就是在thread的生命周期內(nèi)維持變量。thread沒結(jié)束肯定不會(huì)掉呀~  回復(fù)  更多評(píng)論   

    # re: 關(guān)于ThreadLocal的內(nèi)存泄露[未登錄] 2010-07-03 10:44 楊一

    @m
    那如果thread isdeamon呢,thread不同于普通的對(duì)象  回復(fù)  更多評(píng)論   

    <2010年7月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導(dǎo)航

    公告

    本人在blogjava上發(fā)表的文章及隨筆除特別聲明外均為原創(chuàng)或翻譯,作品受知識(shí)產(chǎn)權(quán)法保護(hù)并被授權(quán)遵從 知識(shí)分享協(xié)議:署名-非商業(yè)性使用-相同方式共享 歡迎轉(zhuǎn)載,請(qǐng)?jiān)谵D(zhuǎn)載時(shí)注明作者姓名(楊一)及出處(m.tkk7.com/yangyi)
    /////////////////////////////////////////
    我的訪問者

    常用鏈接

    留言簿(5)

    隨筆分類(55)

    隨筆檔案(55)

    相冊(cè)

    Java

    其他技術(shù)

    生活

    最新隨筆

    搜索

    積分與排名

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    自強(qiáng)不息


    用心 - 珍惜時(shí)間,勇于創(chuàng)造
    主站蜘蛛池模板: 最新亚洲精品国偷自产在线| 久久综合日韩亚洲精品色| 亚洲综合av一区二区三区不卡 | 亚洲av无码不卡私人影院| 国产一区二区三区亚洲综合 | 亚洲国产av一区二区三区| 另类专区另类专区亚洲| 免费人成在线观看播放国产 | 色www免费视频| 国产18禁黄网站免费观看| 国产大陆亚洲精品国产| 亚洲av中文无码| yellow视频免费在线观看| 亚洲va无码手机在线电影| 午夜精品一区二区三区免费视频| 亚洲五月激情综合图片区| 国产亚洲一区二区三区在线| 成在线人免费无码高潮喷水| 久久亚洲精品中文字幕无码| 6080午夜一级毛片免费看6080夜福利 | a级毛片在线免费| 日本免费人成黄页网观看视频 | 一边摸一边爽一边叫床免费视频| 久久伊人亚洲AV无码网站| 免费无码av片在线观看| 亚洲午夜福利精品久久| 国产午夜精品免费一区二区三区| 亚洲精品福利网泷泽萝拉| 永久免费观看的毛片的网站| 亚洲精品高清国产麻豆专区| 女人让男人免费桶爽30分钟| h视频在线观看免费| 久久精品国产亚洲av水果派 | 丁香婷婷亚洲六月综合色| 日本19禁啪啪无遮挡免费动图| 一本岛v免费不卡一二三区| 久久久无码精品亚洲日韩京东传媒| 成人免费在线观看网站| 精品人妻系列无码人妻免费视频 | 亚洲伦另类中文字幕| 国语成本人片免费av无码|