強引用、軟引用、弱引用、虛引用以及ThreadLocal原理

一. 強引用、軟引用、弱引用和虛引用
  • 強引用:使用最普遍的引用,一般情況下,垃圾回收器絕對不會回收它。內(nèi)存不足時,拋出OOM。
String s = new String("hello");
s = null; //不加該行,會輸出hello
System.gc(); //垃圾回收
System.out.println(s);

輸出結(jié)果:null

對象只有在創(chuàng)建它的方法執(zhí)行結(jié)束才會被回收,或者主動設置obj = null。
  • 軟引用:內(nèi)存空間足夠,垃圾回收器不會回收它。反之,則回收。適用于緩存,而且不會OOM。
SoftReference<Object[]> reference = new SoftReference<>(new Object[300000000]);
System.out.println(reference.get());
Object[] objects = new Object[100000000];// 3
System.out.println(reference.get());

輸出結(jié)果:
[Ljava.lang.Object;@4554617c
null

結(jié)果說明執(zhí)行代碼3時,內(nèi)存不夠,垃圾回收器主動回收了軟引用指向的對象。
PS:Object數(shù)組長度根據(jù)JVM配置不同而不同。
  • 弱引用:只有當垃圾回收器掃描到弱引用指向的對象時,才會回收它。生命周期比軟引用更短。ThreadLocal的key使用了弱引用。
WeakReference<String> reference = new WeakReference<>(new String("hello"));
System.out.println(reference.get());
System.gc(); //垃圾回收
System.out.println(reference.get());

輸出結(jié)果:
hello
null
  • 虛引用:在任何時候都可能被垃圾回收器回收,必須與引用隊列關(guān)聯(lián)使用。
ReferenceQueue<String> queue = new ReferenceQueue<>();
PhantomReference<String> reference = new PhantomReference<>(new String("hello"), queue);
System.out.println(reference.get());

輸出結(jié)果:
null
二. ThreadLocal

一個線程可以有多個ThreadLocal實例。其作用是存儲線程本地變量,獨享資源,避免和主內(nèi)存通信,從而提高效率。

原理:都是操作線程中的ThreadLocalMap對象。
set(obj): 獲取當前線程中的ThreadLocalMap,以ThreadLocal實例為key,objvalue,并且key是弱引用。也就是說ThreadLocal實例(未被其他變量強引用)被垃圾回收器掃描到就會被回收,從而導致key = null。這就是為什么get、set、remove的時候都會有清除Entry[]key = null的數(shù)據(jù)的步驟。

remove():會把當前key、value、key-value所在位置Entry[i]置為null,以及清除Entry[]中從i到末尾上key = null的數(shù)據(jù)。

內(nèi)存泄露:key是弱引用,所以垃圾回收器會主動回收。但是valueEntry[i]都是強引用,只有線程銷毀的時候才會被回收。當線程長時間未被銷毀,或者線程池循環(huán)利用線程的時候,valueEntry[i]一直被強引用,不會被垃圾回收器回收,可能會造成OOM。

解決方法:使用完務必調(diào)用remove()方法,防止內(nèi)存泄漏。


以上。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容