ThreadLocal原理介紹及應(yīng)用場(chǎng)景_第1頁(yè)
ThreadLocal原理介紹及應(yīng)用場(chǎng)景_第2頁(yè)
ThreadLocal原理介紹及應(yīng)用場(chǎng)景_第3頁(yè)
ThreadLocal原理介紹及應(yīng)用場(chǎng)景_第4頁(yè)
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第ThreadLocal原理介紹及應(yīng)用場(chǎng)景這一種存在強(qiáng)引用不會(huì)被回收。

這里沒(méi)有強(qiáng)引用將會(huì)被回收。

上面演示了弱引用的回收情況,下面我們看下ThreadLocal的弱引用回收情況。

②ThreadLocal的弱引用回收情況

如上圖所示,我們?cè)谧鳛閗ey的ThreadLocal對(duì)象沒(méi)有外部強(qiáng)引用,下一次gc必將產(chǎn)生key值為null的數(shù)據(jù),若線程沒(méi)有及時(shí)結(jié)束必然出現(xiàn),一條強(qiáng)引用鏈

Threadref–Thread–ThreadLocalMap–Entry,所以這將導(dǎo)致內(nèi)存泄漏。

下面我們模擬復(fù)現(xiàn)ThreadLocal導(dǎo)致內(nèi)存泄漏:

1.為了效果更佳明顯我們將我們的treadlocals的存儲(chǔ)值value設(shè)置為1萬(wàn)字符串的列表:

classThreadLocalMemory{

//Threadlocalvariablecontainingeachthread'sID

publicThreadLocalListObjectthreadId=newThreadLocalListObject(){

@Override

protectedListObjectinitialValue(){

ListObjectlist=newArrayListObject

for(inti=0;i10000;i++){

list.add(String.valueOf(i));

returnlist;

//Returnsthecurrentthread'suniqueID,assigningitifnecessary

publicListObjectget(){

returnthreadId.get();

//removecurrentid

publicvoidremove(){

threadId.remove();

}

測(cè)試代碼如下:

publicstaticvoidmain(String[]args)

throwsInterruptedException{

//為了復(fù)現(xiàn)key被回收的場(chǎng)景,我們使用臨時(shí)變量

ThreadLocalMemorymemeory=newThreadLocalMemory();

//調(diào)用

incrementSameThreadId(memeory);

System.out.println("GC前:key:"+memeory.threadId);

System.out.println("GC前:value-size:"+refelectThreadLocals(Thread.currentThread()));

//設(shè)置為null,調(diào)用gc并不一定觸發(fā)垃圾回收,但是可以通過(guò)java提供的一些工具進(jìn)行手工觸發(fā)gc回收。

memeory.threadId=null;

System.gc();

System.out.println("GC后:key:"+memeory.threadId);

System.out.println("GC后:value-size:"+refelectThreadLocals(Thread.currentThread()));

//模擬線程一直運(yùn)行

while(true){

}

此時(shí)我們?nèi)绾沃纼?nèi)存中存在memoryleak呢?

我們可以借助jdk提供的一些命令dump當(dāng)前堆內(nèi)存,命令如下:

jmap-dump:live,format=b,file=heap.binpid

然后我們借助MAT可視化分析工具,來(lái)查看對(duì)內(nèi)存,分析對(duì)象實(shí)例的存活狀態(tài):

首先打開(kāi)我們工具提示我們的內(nèi)存泄漏分析:

這里我們可以確定的是ThreadLocalMap實(shí)例的Entry.value是沒(méi)有被回收的。

最后我們要確定Entry.key是否還在?打開(kāi)DominatorTree,搜索我們的ThreadLocalMemory,發(fā)現(xiàn)并沒(méi)有存活的實(shí)例。

以上我們復(fù)現(xiàn)了ThreadLocal不正當(dāng)使用,引起的內(nèi)存泄漏。demo在這里。

所以我們總結(jié)了使用ThreadLocal時(shí)會(huì)發(fā)生內(nèi)存泄漏的前提條件:

①ThreadLocal引用被設(shè)置為null,且后面沒(méi)有set,get,remove操作。

②線程一直運(yùn)行,不停止。(線程池)

③觸發(fā)了垃圾回收。(MinorGC或FullGC)

我們看到ThreadLocal出現(xiàn)內(nèi)存泄漏條件還是很苛刻的,所以我們只要破壞其中一個(gè)條件就可以避免內(nèi)存泄漏,單但為了更好的避免這種情況的發(fā)生我們使用ThreadLocal時(shí)遵守以下兩個(gè)小原則:

①ThreadLocal申明為privatestaticfinal。

Private與final盡可能不讓他人修改變更引用,

Static表示為類屬性,只有在程序結(jié)束才會(huì)被回收。

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論