欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Java中的四種引用類型(強(qiáng)軟弱虛)

 更新時(shí)間:2023年10月25日 11:12:24   作者:閑不住的碼  
Java中的引用類型主要分為四種,分別是強(qiáng)引用、軟引用、弱引用和虛引用,這篇文章主要為大家詳細(xì)介紹了四者的使用與區(qū)別,需要的小伙伴可以參考下

強(qiáng)引用(StrongReference)

強(qiáng)引用指的就是代碼中普遍存在的賦值方式,比如A a = new A()這種。強(qiáng)引用關(guān)聯(lián)的對(duì)象,永遠(yuǎn)不會(huì)被GC回收。

當(dāng)內(nèi)存空間不足的時(shí)候,java虛擬機(jī)寧愿拋出OutOfMemoryError 錯(cuò)誤,是程序異常終止,也不會(huì)回收具有強(qiáng)引用的對(duì)象來(lái)解決內(nèi)存不足的問(wèn)題

obj=null //幫助垃圾回收器回收這個(gè)對(duì)象

顯式地設(shè)置obj為null,或者說(shuō)超出對(duì)象的生命周期范圍,則GC認(rèn)為該對(duì)象不存在引用,這時(shí)候就可以回收這個(gè)對(duì)象了,具體什么時(shí)候回收這要看GC的算法是怎么樣的。

當(dāng)一個(gè)方法的內(nèi)部有一個(gè)強(qiáng)引用,這個(gè)引用保存在棧中,而這個(gè)引用的內(nèi)容存放在堆中,當(dāng)這個(gè)方法運(yùn)行完成后就會(huì)退出方法棧,那么引用內(nèi)容也會(huì)跟著就會(huì)不存在了,這個(gè)Object就會(huì)被回收。但是如果個(gè)這個(gè)obj是一個(gè)全局變量的時(shí)候,就需要再不用的時(shí)候?qū)①x值為null,因?yàn)閺?qiáng)引用是不會(huì)被垃圾回收的

在ArrayList的clear方法中就用到了強(qiáng)引用

private transient Object[] elementData;
 
public void clear() {
    modCount++;
     // clear to let GC do its work
    for (int i = 0; i < size; i++) {
        elementData[i] = null;
    }
    size = 0;
}

在 ArrayList 類中定義了一個(gè)私有的變量 elementData 數(shù)組,在調(diào)用方法清空數(shù)組時(shí)可以看到為每個(gè)數(shù)組內(nèi)容賦值為null。 不同于elementData = null,強(qiáng)引用仍然存在,避免在后續(xù)調(diào)用 add()等方法添加元素時(shí),進(jìn)行重新的內(nèi)存分配。使用如 clear() 方法中釋放內(nèi)存的方法對(duì)數(shù)組中存放的引用類型特別適用,這樣就可以及時(shí)釋放內(nèi)存。

軟引用(SoftReference)

軟引用可以用SoftReference來(lái)描述,指的是那些有用但是不是必須要的對(duì)象。系統(tǒng)在發(fā)生內(nèi)存溢出前會(huì)對(duì)這類引用的對(duì)象進(jìn)行回收。

軟引用可以用來(lái)實(shí)現(xiàn)內(nèi)存敏感的高速緩存

軟引用自身不會(huì)被垃圾回收,因?yàn)镚C Root還引用著,軟引用自身需要配合引用隊(duì)列來(lái)釋放。

String str = new String("abc"); // 強(qiáng)引用
SoftReference<String> softRef = new SoftReference<String>(str); // 軟引用  
// 當(dāng)內(nèi)存不足時(shí),等價(jià)于:
if (JVM.內(nèi)存不足()) {//當(dāng)內(nèi)存不夠的時(shí)候就回收
   str = null;  // 轉(zhuǎn)換為軟引用
   System.gc(); // 垃圾回收器進(jìn)行回收
}

軟引用在實(shí)際中有重要的應(yīng)用:

瀏覽器的后退按鈕。按后退時(shí),這個(gè)后退時(shí)顯示的網(wǎng)頁(yè)內(nèi)容是重新進(jìn)行請(qǐng)求還是從緩存中取出呢?這就要看具體的實(shí)現(xiàn)策略了。

  • 獲取頁(yè)面進(jìn)行瀏覽,瀏覽完成后就可以將頁(yè)面設(shè)置為軟應(yīng)用
  • 當(dāng)點(diǎn)擊回退按鈕到先前瀏覽過(guò)的頁(yè)面后,判斷是否被垃圾回收機(jī)制回收了,沒(méi)有回收就直接用,如果回收了,就在重新構(gòu)建頁(yè)面

軟引用可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用,當(dāng)引用的對(duì)象被垃圾回收器回收后,JVM會(huì)自動(dòng)把這個(gè)軟引用加入到和它相關(guān)的這個(gè)引用隊(duì)列中

弱引用(WeakReference)

弱引用可以用WeakReference來(lái)描述,他的強(qiáng)度比軟引用更低一點(diǎn),弱引用的對(duì)象下一次GC的時(shí)候一定會(huì)被回收,而不管內(nèi)存是否足夠。 不過(guò),由于垃圾回收器是一個(gè)優(yōu)先級(jí)很低的線程,因此不一定會(huì)很快發(fā)現(xiàn)那些只具有弱引用的對(duì)象。

弱引用與軟引用的區(qū)別在于:只具有弱引用的對(duì)象擁有更短暫的生命周期。

String str = new String("abc"); //強(qiáng)引用
WeakReference<String> weakRef = new WeakReference<String>(str); // 弱引用
str = null;
 
// 當(dāng)垃圾回收器進(jìn)行掃描回收時(shí)等價(jià)于:
str = null;
System.gc(); // 垃圾回收器進(jìn)行回收
 
// 下面的代碼會(huì)讓str再次變?yōu)橐粋€(gè)強(qiáng)引用:
str = weakRef.get();

使用場(chǎng)景:

  • 如果這個(gè)對(duì)象是偶爾的使用,并且希望在使用時(shí)隨時(shí)就能獲取到,但又不想影響此對(duì)象的垃圾收集,那么你應(yīng)該用弱引用來(lái)記住此對(duì)象。
  • 當(dāng)你想引用一個(gè)對(duì)象,但是這個(gè)對(duì)象有自己的生命周期,你不想介入這個(gè)對(duì)象的生命周期,這時(shí)候你就可以使用弱引用。這個(gè)引用不會(huì)在對(duì)象的垃圾回收判斷中產(chǎn)生任何附加的影響。

弱引用可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用,如果弱引用所引用的對(duì)象被垃圾回收,Java虛擬機(jī)就會(huì)把這個(gè)弱引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。

虛引用(PhantomReference)

虛引用也被稱作幻影引用,是最弱的引用關(guān)系,可以用PhantomReference來(lái)描述,他必須和ReferenceQueue一起使用,同樣的當(dāng)發(fā)生GC的時(shí)候,虛引用也會(huì)被回收。

虛引用與其他幾種引用都不同,它并不會(huì)決定對(duì)象的生命周期。如果一個(gè)對(duì)象僅持有虛引用,那么它就和沒(méi)有任何引用一樣,在任何時(shí)候都可能被垃圾回收器回收。

虛引用與軟引用和弱引用的一個(gè)區(qū)別在于: 虛引用必須和引用隊(duì)列 (ReferenceQueue)聯(lián)合使用。當(dāng)垃圾回收器準(zhǔn)備回收一個(gè)對(duì)象時(shí),如果發(fā)現(xiàn)它還有虛引用,就會(huì)在回收對(duì)象的內(nèi)存之前,把這個(gè)虛引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。

應(yīng)用場(chǎng)景:

  • 程序可以通過(guò)判斷引用隊(duì)列中是否存在該對(duì)象的虛引用,來(lái)了解這個(gè)對(duì)象是否將要被回收??梢?strong>用來(lái)作為GC回收Object的標(biāo)志。
  • 可以用虛引用來(lái)管理堆外內(nèi)存。

Reference和ReferenceQueue

四大引用的父類Reference和ReferenceQueue

在Reference中有5個(gè)非常重要的屬性:referent,next,discovered,pending,queue。

//5個(gè)非常重要的屬性
private T referent;         /* Treated specially by GC */
volatile ReferenceQueue<? super T> queue;
Reference next;
transient private Reference<T> discovered;  /* used by VM */
private static Reference<Object> pending = null;

可以把每個(gè)Reference看做一個(gè)節(jié)點(diǎn),多個(gè)Reference通過(guò)next,discovered,pending 進(jìn)行關(guān)聯(lián)

  • referent就是Reference實(shí)際引用的對(duì)象。
  • 通過(guò)next屬性,可以構(gòu)建ReferenceQueue。
  • 通過(guò)discovered屬性,可以構(gòu)建Discovered List。
  • 通過(guò)pending屬性,可以構(gòu)建Pending List。

四大狀態(tài)

上圖就是Reference 的四個(gè)狀態(tài)

  //Reference的兩個(gè)構(gòu)造方法,一個(gè)帶隊(duì)列,一個(gè)不帶
Reference(T referent) { 
        this(referent, null);
    }
?
    Reference(T referent, ReferenceQueue<? super T> queue) {
        this.referent = referent;
        this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
    }
?

對(duì)于帶ReferenceQueue的Reference,GC會(huì)把要回收對(duì)象的Reference放到ReferenceQueue中,后續(xù)該Reference需要程序員自己處理 (調(diào)用poll方法) 。

不帶ReferenceQueue的Reference, 由GC自己處理,待回收的對(duì)象其Reference狀態(tài)會(huì)變成Inactive。

  • 創(chuàng)建好了Reference,就進(jìn)入active狀態(tài)。
  • active狀態(tài)下,如果引用對(duì)象的可到達(dá)狀態(tài)發(fā)送變化就會(huì)轉(zhuǎn)變成Inactive或Pending狀態(tài)。
  • Inactive狀態(tài)很好理解,到達(dá)Inactive狀態(tài)的Reference狀態(tài)不能被改變,會(huì)等待GC回收。
  • Pending狀態(tài)代表等待入Queue,Reference內(nèi)部有個(gè)ReferenceHandler,會(huì)調(diào)用enqueue方法,將Pending對(duì)象入到Queue中入Queue的對(duì)象,其狀態(tài)就變成了Enqueued。
  • Enqueued狀態(tài)的對(duì)象,如果調(diào)用poll方法從ReferenceQueue拿出,則該Reference的狀態(tài)就變成了Inactive,等待GC的回收。

這就是Reference的一個(gè)完整的生命周期。

三個(gè)Queue/List

三個(gè)Queue/List:ReferenceQueue,discovered List和pending List

  • ReferenceQueue它本質(zhì)是由Reference中的next連接而成的。用來(lái)存儲(chǔ)GC待回收的對(duì)象。
  • pending List就是待入ReferenceQueue的list。
  • discovered List這個(gè)有點(diǎn)特別,在Pending狀態(tài)時(shí)候,discovered List就等于pending List。 在Active狀態(tài)的時(shí)候discovered List實(shí)際上維持的是一個(gè)引用鏈。通過(guò)這個(gè)引用鏈,我們可以獲得引用的鏈?zhǔn)浇Y(jié)構(gòu),當(dāng)某個(gè)Reference狀態(tài)不再是Active狀態(tài)時(shí),需要將這個(gè)Reference從discovered List中刪除。

總結(jié)

Java的四種引用的級(jí)別由高到低依次為:強(qiáng)引用 > 軟引用 > 弱引用 > 虛引用

回收時(shí)機(jī)用途生存時(shí)間
強(qiáng)重來(lái)不會(huì)對(duì)象的一般狀態(tài)JVM停止運(yùn)行時(shí)終止
內(nèi)存不足 時(shí)聯(lián)合引用隊(duì)列構(gòu)造有效期短、占內(nèi)存大,生命周期長(zhǎng)的對(duì)象的二級(jí)高速緩沖器(內(nèi)存不足的時(shí)候清空)內(nèi)存不足 時(shí)終止
在垃圾回收時(shí)聯(lián)合引用隊(duì)列構(gòu)造有效期短、占內(nèi)存大,生命周期長(zhǎng)的對(duì)象的一級(jí)高速緩沖器(發(fā)生GC的時(shí)候清空)GC運(yùn)行后終止
在垃圾回收時(shí)聯(lián)合引用隊(duì)列來(lái)跟蹤對(duì)象被垃圾回收器回收的活動(dòng)GC運(yùn)行后終止

以上就是詳解Java中的四種引用類型(強(qiáng)軟弱虛)的詳細(xì)內(nèi)容,更多關(guān)于Java引用類型的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringBoot中EasyExcel實(shí)現(xiàn)execl導(dǎo)入導(dǎo)出

    SpringBoot中EasyExcel實(shí)現(xiàn)execl導(dǎo)入導(dǎo)出

    本文主要介紹了SpringBoot中EasyExcel實(shí)現(xiàn)execl導(dǎo)入導(dǎo)出,實(shí)現(xiàn)了如何準(zhǔn)備環(huán)境、創(chuàng)建實(shí)體類、自定義轉(zhuǎn)換器以及編寫導(dǎo)入邏輯的步驟和示例代碼,感興趣的可以了解下
    2023-06-06
  • springboot docker原理及項(xiàng)目構(gòu)建

    springboot docker原理及項(xiàng)目構(gòu)建

    這篇文章主要介紹了springboot docker原理及項(xiàng)目構(gòu)建,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Spring cloud config 配置文件加密方式

    Spring cloud config 配置文件加密方式

    這篇文章給大家介紹了Spring cloud config 配置文件加密方式,非常不錯(cuò),具有一定的參考借鑒價(jià)值,感興趣的朋友跟隨腳步之家小編一起學(xué)習(xí)吧
    2018-05-05
  • java常用Lambda表達(dá)式使用場(chǎng)景源碼示例

    java常用Lambda表達(dá)式使用場(chǎng)景源碼示例

    這篇文章主要為大家介紹了java常用Lambda表達(dá)式使用場(chǎng)景源碼示例及應(yīng)用解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-03-03
  • Spring注解配置實(shí)現(xiàn)過(guò)程詳解

    Spring注解配置實(shí)現(xiàn)過(guò)程詳解

    這篇文章主要介紹了Spring注解配置實(shí)現(xiàn)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Java排序算法三之歸并排序的遞歸與非遞歸的實(shí)現(xiàn)示例解析

    Java排序算法三之歸并排序的遞歸與非遞歸的實(shí)現(xiàn)示例解析

    這篇文章主要介紹了Java排序算法三之歸并排序的遞歸與非遞歸的實(shí)現(xiàn)示例解析,文章通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Java定時(shí)器Timer的源碼分析

    Java定時(shí)器Timer的源碼分析

    通過(guò)源碼分析,我們可以更深入的了解其底層原理。本文將通過(guò)Timer的源碼,帶大家深入了解Java?Timer的使用,感興趣的小伙伴可以了解一下
    2022-11-11
  • Java Idea高效率配置技巧實(shí)例解析

    Java Idea高效率配置技巧實(shí)例解析

    這篇文章主要介紹了Java Idea高效率配置技巧實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Spring學(xué)習(xí)筆記3之消息隊(duì)列(rabbitmq)發(fā)送郵件功能

    Spring學(xué)習(xí)筆記3之消息隊(duì)列(rabbitmq)發(fā)送郵件功能

    這篇文章主要介紹了Spring學(xué)習(xí)筆記3之消息隊(duì)列(rabbitmq)發(fā)送郵件功能的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • 聊聊Spring?Cloud?Gateway過(guò)濾器精確控制異常返回問(wèn)題

    聊聊Spring?Cloud?Gateway過(guò)濾器精確控制異常返回問(wèn)題

    這篇文章主要介紹了Spring?Cloud?Gateway過(guò)濾器精確控制異常返回問(wèn)題,本篇任務(wù)就是分析上述現(xiàn)象的原因,通過(guò)閱讀源碼搞清楚返回碼和響應(yīng)body生成的具體邏輯,需要的朋友可以參考下
    2021-11-11

最新評(píng)論