對(duì)比
不同點(diǎn)
類型 | 類名 | 數(shù)據(jù)獲取方式 | 回收策略 | 場(chǎng)景 |
---|---|---|---|---|
強(qiáng)引用 | 正常引用 | 直接獲取 | JVM 停止 | 正常使用 |
軟引用 | SoftReference 構(gòu)造方法有 SoftReference(T) 和 SoftReference(T, java.lang.ref.ReferenceQueue<? super T>) | softReference.get(),可能為空 | 垃圾回收期拋出 OutOfMemoryError 之前回收 | 緩存大對(duì)象炊甲,避免OOM泥彤;如瀏覽器的后退按鈕、對(duì)象緩存卿啡,但是需要在獲取時(shí)判斷是否為空吟吝,并針對(duì)處理 |
弱引用 | WeakReference 構(gòu)造方法同上 | weakReference.get(),可能為空 | 當(dāng)JVM進(jìn)行垃圾回收時(shí)颈娜,無論內(nèi)存是否充足剑逃,一旦垃圾回收線程發(fā)現(xiàn)了弱引用對(duì)象,在下一次GC過程中就會(huì)對(duì)其進(jìn)行回收 | 如果一個(gè)對(duì)象是偶爾(很少)的使用官辽,并且希望在使用時(shí)隨時(shí)就能獲取到蛹磺,但又不想影響此對(duì)象的垃圾收集,那么你應(yīng)該用Weak Reference來記住此對(duì)象 |
虛引用 | PhantomReference 構(gòu)造方法只有 WeakReference(T, java.lang.ref.ReferenceQueue<? super T>) | phantomReference.get() 永遠(yuǎn)為 null | 形同虛設(shè)同仆,和沒引用一樣 | 虛引用主要用來跟蹤對(duì)象被垃圾回收器回收的活動(dòng)萤捆,虛引用必須和引用隊(duì)列(ReferenceQueue)聯(lián)合使用。當(dāng)垃圾回收器準(zhǔn)備回收一個(gè)對(duì)象時(shí)俗批,如果發(fā)現(xiàn)它還有虛引用俗或,就會(huì)在回收對(duì)象的內(nèi)存之前,把這個(gè)虛引用加入到與之關(guān)聯(lián)的引用隊(duì)列中 |
相同點(diǎn)
軟岁忘、弱辛慰、虛引用都是 JVM 里面的概念,都可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用干像,如果所引用的對(duì)象被垃圾回收帅腌,Java虛擬機(jī)就會(huì)把這個(gè)引用加入到與之關(guān)聯(lián)的引用隊(duì)列中驰弄。
相關(guān)代碼
軟引用、弱引用轉(zhuǎn)強(qiáng)
String str = new String("test");
WeakReference<String> weakReference = new WeakReference<>(str);
// 弱引用轉(zhuǎn)強(qiáng)引用
String strongReference = weakReference.get();
String str1 = new String("test");
SoftReference<String> softReference = new SoftReference<>(str);
// 軟引用轉(zhuǎn)強(qiáng)引用
String strongReference1 = softReference.get();
瀏覽器頁(yè)面緩存
// 從后臺(tái)程序加載瀏覽頁(yè)面
BrowserPage page = browser.getPage();
// 將瀏覽完畢的頁(yè)面置為軟引用
SoftReference softReference = new SoftReference(page);
// 回退或者再次瀏覽此頁(yè)面時(shí)
if(softReference.get() != null) {
// 內(nèi)存充足速客,還沒有被回收器回收戚篙,直接獲取緩存
page = softReference.get();
} else {
// 內(nèi)存不足,軟引用的對(duì)象已經(jīng)回收
page = browser.getPage();
// 重新構(gòu)建軟引用
softReference = new SoftReference(page);
}
引用的使用
// 聲明一個(gè)強(qiáng)引用
Object strongReference = new Object();
// 弱化從而使GC能夠回收
strongReference = null;
// 強(qiáng)引用變量
String str = new String("test");
// 指定為軟引用
SoftReference<String> softReference = new SoftReference<String>(str);
str = null;
// 垃圾收集線程會(huì)在虛擬機(jī)拋出 OutOfMemoryError 之前回收軟引用對(duì)象挽封,這里才會(huì)返回空
softReference.get();
ReferenceQueue<String> referenceQueue = new ReferenceQueue<>();
// 弱引用
WeakReference<String> weakReference = new WeakReference<>(new String("test"), referenceQueue);
// 通知 GC 進(jìn)行垃圾回收已球,真正執(zhí)行時(shí)間不確定
System.gc();
// 不一定返回空,得等到下次 GC 才能返回空
softReference.get();
// 虛引用
PhantomReference phantomReference = new PhantomReference(new String("test"),referenceQueue);
// 一定是空
phantomReference.get();
參考文章
https://juejin.im/post/5b82c02df265da436152f5ad
https://www.cnblogs.com/dolphin0520/p/3784171.html