簡介
從JDK1.2版本開始,把對象的引用分為四種級別,從而使程序能更加靈活的控制對象的生命周期。這四種級別由高到低依次為:強引用、軟引用、弱引用和虛引用,下面分別介紹下這四種引用。
強引用
強引用是最常用的引用類型,如下所示,new Object()會創(chuàng)建一個Object對象并存儲在堆上,變量object存儲對該對象的強引用。
Object object = new Object();
強引用不會被垃圾回收,所以要想回收該對象,則應(yīng)該將指向該對象的變量顯示設(shè)為null,這樣該對象就由強引用轉(zhuǎn)變?yōu)闊o引用了。
示例:
public class ReferenceDemo {
public static void main(String[] args) throws IOException {
//強引用不會被垃圾回收
ReferenceDemo referenceDemo = new ReferenceDemo();
//強引用轉(zhuǎn)變?yōu)闊o引用,無引用可被垃圾回收
referenceDemo = null;
//觸發(fā)垃圾回收
System.gc();
//阻塞主線程,等待垃圾回收線程執(zhí)行
System.in.read();
}
//對象被回收之前調(diào)用
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("-----finalize-----");
}
}
軟引用
軟引用是使用SoftReference創(chuàng)建的,在內(nèi)存空間充足的情況下,軟引用不會被回收,而在內(nèi)存空間不足虛擬機拋出OutOfMemoryError之前,軟引用將會被回收。
示例:
public class ReferenceDemo {
public static void main(String[] args) throws InterruptedException {
//創(chuàng)建ReferenceDemo對象的軟引用
SoftReference<ReferenceDemo> softReference = new SoftReference<>(new ReferenceDemo());
//觸發(fā)垃圾回收
System.gc();
//阻塞主線程,等待垃圾回收線程執(zhí)行
Thread.sleep(5000);
//softReference.get()返回軟引用對象,如果對象已經(jīng)被垃圾回收,則返回null
System.out.println(softReference.get());
//創(chuàng)建25M的字節(jié)數(shù)組
byte[] bytes = new byte[1024 * 1024 * 25];
//內(nèi)存已經(jīng)不足,阻塞主線程,等待垃圾回收線程執(zhí)行
Thread.sleep(5000);
//重新輸出軟引用對象
System.out.println(softReference.get());
}
}
/*
* 輸出結(jié)果:
* com.buhe.demo.demos.reference.ReferenceDemo@76fb509a
* null
*/
注意:示例運行前需要設(shè)置堆內(nèi)存大小為30M(-Xmx30m -Xms30m)。
用途:軟引用可以用于對內(nèi)存空間敏感的緩存,緩存的對象一直保存,直到內(nèi)存空間不足而被回收。
弱引用
弱引用是使用WeakReference創(chuàng)建的,在垃圾回收線程執(zhí)行過程中,只要找到了弱引用,不管內(nèi)存空間是否足夠,弱引用對象都將被回收。由于垃圾回收線程是一個優(yōu)先級很低的線程,因此不一定會很快發(fā)現(xiàn)那些只具有弱引用的對象。
示例:
public class ReferenceDemo {
public static void main(String[] args) throws InterruptedException {
//創(chuàng)建ReferenceDemo的弱引用
WeakReference<ReferenceDemo> weakReference = new WeakReference<>(new ReferenceDemo());
//weakReference.get()返回弱引用對象,如果對象已經(jīng)被垃圾回收,則返回null
System.out.println(weakReference.get());
//觸發(fā)垃圾回收
System.gc();
//阻塞主線程,等待垃圾回收線程執(zhí)行
Thread.sleep(3000);
//重新輸出弱引用對象
System.out.println(weakReference.get());
}
}
/*
* 輸出結(jié)果:
* com.buhe.demo.demos.reference.ReferenceDemo@76fb509a
* null
*/
用途:弱引用也可以用于緩存,可以參考WeakHashMap類。
虛引用
虛引用是使用PhantomReference創(chuàng)建的,它是所以引用類型中最弱的。虛引用對象和沒有引用的對象相同,可以在任何時候被垃圾回收,并且虛引用必須要與引用隊列一起使用。
當(dāng)垃圾回收線程回收一個虛引用對象時,它將在垃圾回收后銷毀該對象,并將PhantomReference添加到引用隊列中。
示例:
public class ReferenceDemo {
public static void main(String[] args) throws InterruptedException {
//創(chuàng)建引用隊列
ReferenceQueue<Object> referenceQueue = new ReferenceQueue();
//創(chuàng)建ReferenceDemo的虛引用
PhantomReference<ReferenceDemo> phantomReference = new PhantomReference<>(new ReferenceDemo(), referenceQueue);
//phantomReference.get()總是返回null
System.out.println("phantomReference.get():" + phantomReference.get());
//輪詢此隊列,查看是否有可用的Reference對象,有則返回該對象,否則返回null
System.out.println("referenceQueue.poll():" + referenceQueue.poll());
//觸發(fā)垃圾回收
System.gc();
//阻塞主線程,等待垃圾回收線程執(zhí)行
Thread.sleep(3000);
System.out.println("------垃圾回收之后------");
System.out.println("phantomReference.get():" + phantomReference.get());
System.out.println("referenceQueue.poll():" + referenceQueue.poll());
}
}
/*
* 輸出結(jié)果:
* phantomReference.get():null
* referenceQueue.poll():null
* ------垃圾回收之后------
* phantomReference.get():null
* referenceQueue.poll():java.lang.ref.PhantomReference@76fb509a
*/
用途:虛引用可以用于精確的檢測對象何時從內(nèi)存中刪除,通過檢查引用隊列來判斷對象是否已經(jīng)被回收。
以上就是關(guān)于 Java 中四種引用類型的簡要概述和使用方法的全部內(nèi)容,想要了解更多關(guān)于Java 引用類型的其他資料請關(guān)注W3Cschool其它相關(guān)文章!如果本篇文章對您的學(xué)習(xí)有所幫助,還希望大家能夠多多地支持我們!