簡(jiǎn)述Java中的四種引用類型
簡(jiǎn)介
從JDK1.2版本開(kāi)始,把對(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)文章
Java程序設(shè)計(jì)之12個(gè)經(jīng)典樣例
這篇文章主要給大家分享關(guān)于Java程序設(shè)計(jì)11個(gè)經(jīng)典樣例,主要以舉例的形式詳細(xì)的講解了Java程序設(shè)計(jì)的各種方法,需要的朋友可以參考一下文章具體的內(nèi)容2021-10-10如何修改json字符串中某個(gè)key對(duì)應(yīng)的value值
這篇文章主要介紹了如何修改json字符串中某個(gè)key對(duì)應(yīng)的value值操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11Java實(shí)現(xiàn)通過(guò)IP獲取IP歸屬地的方法(離線+在線)
我們都知道安全攻擊都是在某臺(tái)客戶機(jī)上執(zhí)行某些惡意操作致使服務(wù)端響應(yīng)異常崩潰亦或響應(yīng)數(shù)據(jù)被篡改,首先我想到的是對(duì)訪問(wèn)的web端做一個(gè)IP的校驗(yàn),那么我們首先得知道客戶端的IP是多少,接下來(lái)此文重點(diǎn)介紹如何獲得,需要的朋友可以參考下2023-10-10mybatis使用foreach語(yǔ)句實(shí)現(xiàn)IN查詢(三種)
這篇文章主要介紹了mybatis使用foreach語(yǔ)句實(shí)現(xiàn)IN查詢(三種),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12Spring Boot實(shí)現(xiàn)簡(jiǎn)單的增刪改查
這篇文章主要介紹了Spring Boot如何實(shí)現(xiàn)簡(jiǎn)單的增刪改查,幫助大家更好的理解和學(xué)習(xí)spring boot框架,感興趣的朋友可以了解下2020-09-09Java實(shí)現(xiàn)Socket的TCP傳輸實(shí)例
這篇文章主要介紹了Java實(shí)現(xiàn)Socket的TCP傳輸,實(shí)例分析了java通過(guò)socket實(shí)現(xiàn)TCP傳輸?shù)南嚓P(guān)技巧,需要的朋友可以參考下2015-05-05詳解設(shè)計(jì)模式中的proxy代理模式及在Java程序中的實(shí)現(xiàn)
代理模式主要分為靜態(tài)代理和動(dòng)態(tài)代理,使客戶端方面的使用者通過(guò)設(shè)置的代理來(lái)操作對(duì)象,下面來(lái)詳解設(shè)計(jì)模式中的proxy代理模式及在Java程序中的實(shí)現(xiàn)2016-05-05