Java 強軟弱虛引用
本文參考內(nèi)容:
https://www.51cto.com/article/686209.html

本文分成以下幾個部分:
介紹強軟弱虛四種引用
為什么在ThreadLocal中使用的是WeakReference
ThreadLocal中出現(xiàn)的內(nèi)存泄露的問題

強引用
強引用不用多說,我們主要寫的代碼都是強引用:
句柄a放在虛擬機棧上,new創(chuàng)建出來的A放在堆中。設(shè)置a = null就會使得在堆中的A沒有被引用到,這樣就會被gc。
軟引用
軟引用會在內(nèi)存不足時被釋放:
設(shè)置內(nèi)存為20M,輸出為:
當創(chuàng)建第二個內(nèi)存為10M的byte數(shù)組時,內(nèi)存不夠,就會回收軟引用。
弱引用
弱引用會在gc的時候直接被釋放,不管有無空閑的內(nèi)存:
第二個輸出為空
虛引用
通過虛引用的get方法只能返回null,而且虛引用必須要和Reference隊列聯(lián)合使用。它主要是實現(xiàn)一個對象回收的監(jiān)聽過程。

ThreadLocal部分源碼分析
ThreadLocal是基于一個類似于Map的結(jié)構(gòu)實現(xiàn)的保證線程數(shù)據(jù)的獨立性:

ThreadLocalMap是基于Entry的結(jié)構(gòu):
Entry是一個WeakReference,同時在Entry的構(gòu)造方法中也將ThreadLocal套了一層弱引用。

所以在棧區(qū),tl句柄強引用指向?qū)χ氐腡hreadLocal,同時棧區(qū)的Key也通過弱引用的方式指向Threadlocal。這樣我們不想使用ThreadLocal時,tl= null,然后gc就可以清除掉ThreadLocal。但是此時,Value對象還有強引用指向,所以Value對象可能會造成泄漏,只能等到線程結(jié)束。
總而言之,如果所示:
