簡(jiǎn)述Java中的四種引用類型
簡(jiǎn)介
從JDK1.2版本開始,把對(duì)象的引用分為四種級(jí)別,從而使程序能更加靈活的控制對(duì)象的生命周期。這四種級(jí)別由高到低依次為:強(qiáng)引用、軟引用、弱引用和虛引用,下面分別介紹下這四種引用。
強(qiáng)引用
強(qiáng)引用是最常用的引用類型,如下所示,new Object()會(huì)創(chuàng)建一個(gè)Object對(duì)象并存儲(chǔ)在堆上,變量object存儲(chǔ)對(duì)該對(duì)象的強(qiáng)引用。
Object object = new Object();
強(qiáng)引用不會(huì)被垃圾回收,所以要想回收該對(duì)象,則應(yīng)該將指向該對(duì)象的變量顯示設(shè)為null,這樣該對(duì)象就由強(qiáng)引用轉(zhuǎn)變?yōu)闊o(wú)引用了。
示例:
public class ReferenceDemo {
public static void main(String[] args) throws IOException {
//強(qiáng)引用不會(huì)被垃圾回收
ReferenceDemo referenceDemo = new ReferenceDemo();
//強(qiáng)引用轉(zhuǎn)變?yōu)闊o(wú)引用,無(wú)引用可被垃圾回收
referenceDemo = null;
//觸發(fā)垃圾回收
System.gc();
//阻塞主線程,等待垃圾回收線程執(zhí)行
System.in.read();
}
//對(duì)象被回收之前調(diào)用
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("-----finalize-----");
}
}
軟引用
軟引用是使用SoftReference創(chuàng)建的,在內(nèi)存空間充足的情況下,軟引用不會(huì)被回收,而在內(nèi)存空間不足虛擬機(jī)拋出OutOfMemoryError之前,軟引用將會(huì)被回收。
示例:
public class ReferenceDemo {
public static void main(String[] args) throws InterruptedException {
//創(chuàng)建ReferenceDemo對(duì)象的軟引用
SoftReference<ReferenceDemo> softReference = new SoftReference<>(new ReferenceDemo());
//觸發(fā)垃圾回收
System.gc();
//阻塞主線程,等待垃圾回收線程執(zhí)行
Thread.sleep(5000);
//softReference.get()返回軟引用對(duì)象,如果對(duì)象已經(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);
//重新輸出軟引用對(duì)象
System.out.println(softReference.get());
}
}
/*
* 輸出結(jié)果:
* com.buhe.demo.demos.reference.ReferenceDemo@76fb509a
* null
*/
注意:示例運(yùn)行前需要設(shè)置堆內(nèi)存大小為30M(-Xmx30m -Xms30m)。
用途:軟引用可以用于對(duì)內(nèi)存空間敏感的緩存,緩存的對(duì)象一直保存,直到內(nèi)存空間不足而被回收。
弱引用
弱引用是使用WeakReference創(chuàng)建的,在垃圾回收線程執(zhí)行過(guò)程中,只要找到了弱引用,不管內(nèi)存空間是否足夠,弱引用對(duì)象都將被回收。由于垃圾回收線程是一個(gè)優(yōu)先級(jí)很低的線程,因此不一定會(huì)很快發(fā)現(xiàn)那些只具有弱引用的對(duì)象。
示例:
public class ReferenceDemo {
public static void main(String[] args) throws InterruptedException {
//創(chuàng)建ReferenceDemo的弱引用
WeakReference<ReferenceDemo> weakReference = new WeakReference<>(new ReferenceDemo());
//weakReference.get()返回弱引用對(duì)象,如果對(duì)象已經(jīng)被垃圾回收,則返回null
System.out.println(weakReference.get());
//觸發(fā)垃圾回收
System.gc();
//阻塞主線程,等待垃圾回收線程執(zhí)行
Thread.sleep(3000);
//重新輸出弱引用對(duì)象
System.out.println(weakReference.get());
}
}
/*
* 輸出結(jié)果:
* com.buhe.demo.demos.reference.ReferenceDemo@76fb509a
* null
*/
用途:弱引用也可以用于緩存,可以參考WeakHashMap類。
虛引用
虛引用是使用PhantomReference創(chuàng)建的,它是所以引用類型中最弱的。虛引用對(duì)象和沒(méi)有引用的對(duì)象相同,可以在任何時(shí)候被垃圾回收,并且虛引用必須要與引用隊(duì)列一起使用。
當(dāng)垃圾回收線程回收一個(gè)虛引用對(duì)象時(shí),它將在垃圾回收后銷毀該對(duì)象,并將PhantomReference添加到引用隊(duì)列中。
示例:
public class ReferenceDemo {
public static void main(String[] args) throws InterruptedException {
//創(chuàng)建引用隊(duì)列
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());
//輪詢此隊(duì)列,查看是否有可用的Reference對(duì)象,有則返回該對(duì)象,否則返回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
*/
用途:虛引用可以用于精確的檢測(cè)對(duì)象何時(shí)從內(nèi)存中刪除,通過(guò)檢查引用隊(duì)列來(lái)判斷對(duì)象是否已經(jīng)被回收。
以上就是簡(jiǎn)述Java中的四種引用類型的詳細(xì)內(nèi)容,更多關(guān)于Java 引用類型的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
利用SpringBoot和LiteFlow解鎖復(fù)雜流程
隨著業(yè)務(wù)的復(fù)雜化,企業(yè)需要更加高效、便捷地管理自己的業(yè)務(wù)流程,這就需要借助一些流程引擎實(shí)現(xiàn),今天,我們就來(lái)介紹一種基于Java語(yǔ)言開發(fā)的輕量級(jí)工作流引擎——LiteFlow,以及如何在Spring Boot框架中集成它,從而提高企業(yè)的工作效率和開發(fā)效率2023-06-06
Springboot接收Get參數(shù)實(shí)踐過(guò)程
本文主要介紹了在Spring Boot中如何接收不同類型的請(qǐng)求參數(shù),包括在路徑中直接傳遞參數(shù)、跟在問(wèn)號(hào)后面?zhèn)鬟f參數(shù)、使用Map接收參數(shù)、接收數(shù)組以及使用對(duì)象接收參數(shù)等方法2024-12-12
IDEA如何對(duì)單個(gè)的java class文件打成jar包
這篇文章主要介紹了IDEA如何對(duì)單個(gè)的java class文件打成jar包問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
java根據(jù)方法名稱取得反射方法的參數(shù)類型示例
利用java反射原理調(diào)用方法時(shí),常先需要傳入方法參數(shù)數(shù)組才能取得方法。該方法參數(shù)數(shù)組采用動(dòng)態(tài)取得的方式比較合適2014-02-02
Java黑科技之通過(guò)Google Java Style 文件配置IDEA和Ecplise代碼風(fēng)格
在日常開發(fā)中,多人團(tuán)隊(duì)協(xié)作開發(fā)一個(gè)項(xiàng)目是很常見的,特別是大公司,這就會(huì)涉及到多人在一個(gè)工程上開發(fā)代碼.無(wú)規(guī)矩不成方圓,一個(gè)好的代碼風(fēng)格,更加有利于團(tuán)隊(duì)協(xié)作,減少代碼沖突,提高代碼可閱讀性,美觀性.本文就帶著大家仔細(xì)研究這個(gè)黑科技 ,需要的朋友可以參考下2021-05-05
Spring框架中一個(gè)有用的小組件之Spring Retry組件詳解
Spring Retry 是從 Spring batch 中獨(dú)立出來(lái)的一個(gè)功能,主要實(shí)現(xiàn)了重試和熔斷,對(duì)于那些重試后不會(huì)改變結(jié)果,毫無(wú)意義的操作,不建議使用重試,今天通過(guò)本文給大家介紹Spring Retry組件詳解,感興趣的朋友一起看看吧2021-07-07
springboot自動(dòng)裝配之@ComponentScan使用方式
@componentScan注解用于掃描指定路徑下的組件,并自動(dòng)將它們注冊(cè)為Spring?Bean,該注解支持多種過(guò)濾規(guī)則,可以自定義掃描過(guò)濾規(guī)則,Spring?Boot通過(guò)ConfigurationClassPostProcessor處理@ComponentScan注解,并在啟動(dòng)時(shí)創(chuàng)建和注冊(cè)BeanDefinition對(duì)象2025-01-01

