最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解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)文章

  • java生成文件夾和文件的簡(jiǎn)單示例分享

    java生成文件夾和文件的簡(jiǎn)單示例分享

    這篇文章主要介紹了java生成文件夾和文件的簡(jiǎn)單示例,需要的朋友可以參考下
    2014-04-04
  • Maven pom中optional配置項(xiàng)詳解及依賴調(diào)解原則

    Maven pom中optional配置項(xiàng)詳解及依賴調(diào)解原則

    Maven pom中optional配置項(xiàng)詳解及依賴調(diào)解原則,情況行為(默認(rèn))依賴會(huì)傳遞給下游項(xiàng)目依賴僅當(dāng)前項(xiàng)目可用,不會(huì)傳遞當(dāng)前項(xiàng)目和依賴項(xiàng)目都依賴同一包Maven按“路徑最近”原則選擇版本可選依賴+下游未顯
    2025-10-10
  • 項(xiàng)目依賴Springboot jar失敗解決方案

    項(xiàng)目依賴Springboot jar失敗解決方案

    這篇文章主要介紹了項(xiàng)目依賴Springboot jar失敗解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Java默認(rèn)傳入時(shí)間段時(shí)間的實(shí)例

    Java默認(rèn)傳入時(shí)間段時(shí)間的實(shí)例

    下面小編就為大家?guī)?lái)一篇Java默認(rèn)傳入時(shí)間段時(shí)間的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • Java 網(wǎng)絡(luò)編程總結(jié)

    Java 網(wǎng)絡(luò)編程總結(jié)

    這篇文章主要給大家分享Java 網(wǎng)絡(luò)編程的一個(gè)總結(jié),說(shuō)到網(wǎng)絡(luò)編程肯定都會(huì)想到IP地址、端口、通信協(xié)議等一些必不可少的元素,下面來(lái)看看文章的詳細(xì)介紹吧
    2021-11-11
  • 2021年最新Redis面試題匯總(2)

    2021年最新Redis面試題匯總(2)

    在程序員面試過(guò)程中redis相關(guān)的知識(shí)是常被問(wèn)到的話題。這篇文章主要介紹了幾道Redis面試題,整理一下分享給大家,感興趣的小伙伴們可以參考一下
    2021-07-07
  • idea中創(chuàng)建jsp項(xiàng)目的詳細(xì)實(shí)戰(zhàn)步驟

    idea中創(chuàng)建jsp項(xiàng)目的詳細(xì)實(shí)戰(zhàn)步驟

    才學(xué)javaWeb,以防自己忘記創(chuàng)建項(xiàng)目的過(guò)程,所以淺淺的記錄一下吧,下面這篇文章主要給大家介紹了關(guān)于idea中創(chuàng)建jsp項(xiàng)目的詳細(xì)步驟,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • Mybatis-Mapper.xml文件前綴詳解

    Mybatis-Mapper.xml文件前綴詳解

    這篇文章主要介紹了Mybatis-Mapper.xml文件前綴,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • util.Date與sql.Date的相互轉(zhuǎn)換過(guò)程

    util.Date與sql.Date的相互轉(zhuǎn)換過(guò)程

    本文介紹了Java中兩個(gè)常用日期類的區(qū)別和相互轉(zhuǎn)換方法,包括java.util.Date和java.sql.Date,并展示了如何使用SimpleDateFormat進(jìn)行日期格式化
    2026-01-01
  • Java三種IO模型原理實(shí)例詳解

    Java三種IO模型原理實(shí)例詳解

    這篇文章主要介紹了Java三種IO模型原理實(shí)例詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05

最新評(píng)論

彭州市| 德化县| 清新县| 汤阴县| 宣恩县| 稻城县| 枝江市| 东宁县| 崇仁县| 宜春市| 故城县| 南和县| 九寨沟县| 浮梁县| 新邵县| 枣庄市| 平南县| 汝阳县| 昌邑市| 军事| 龙川县| 鄢陵县| 依安县| 凤庆县| 宜春市| 全椒县| 运城市| 奉新县| 西充县| 石家庄市| 锡林浩特市| 云安县| 兖州市| 平定县| 民乐县| 武定县| 灯塔市| 惠来县| 五指山市| 临安市| 上杭县|