成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

深入解析強(qiáng)引用、軟引用、弱引用、幻象引用

Bmob / 3441人閱讀

摘要:弱引用與軟引用最大的區(qū)別就是弱引用比軟引用的生命周期更短暫。所以對(duì)于軟引用弱引用之類,垃圾收集器可能會(huì)存在二次確認(rèn)的問(wèn)題,以確保處于弱引用狀態(tài)的對(duì)象沒(méi)有改變?yōu)閺?qiáng)引用。

關(guān)于強(qiáng)引用、軟引用、弱引用、幻象引用的區(qū)別,在一些大公司的面試題中經(jīng)常出現(xiàn),可能有些小伙伴覺(jué)得這個(gè)知識(shí)點(diǎn)比較冷門,但其實(shí)大家在開(kāi)發(fā)中經(jīng)常用到,如new一個(gè)對(duì)象的時(shí)候就是強(qiáng)引用的應(yīng)用。

在java語(yǔ)言中,除了原始數(shù)據(jù)類型(boolean、byte、short、char、int、float、double、long)的變量,其他所有都是所謂的引用類型,指向各種不同的對(duì)象。理解這些引用的區(qū)別,對(duì)于掌握java對(duì)象生命周期和JVM內(nèi)部相關(guān)機(jī)制非常有幫助。也有助于更深刻的理解底層對(duì)象生命周期、垃圾收集機(jī)制等,對(duì)設(shè)計(jì)可靠的緩存框架、診斷應(yīng)用OOM等問(wèn)題也大有裨益。

這四種應(yīng)用主要的區(qū)別體現(xiàn)在對(duì)象不同的可達(dá)性狀態(tài)和對(duì)垃圾收集的影響,他們之間的可達(dá)性狀態(tài)可以參看下圖:

1.強(qiáng)引用(strong reference)

強(qiáng)引用就是我們最常見(jiàn)的普通對(duì)象引用(如new 一個(gè)對(duì)象),只要還有強(qiáng)引用指向一個(gè)對(duì)象,就表明此對(duì)象還“活著”。在強(qiáng)引用面前,即使JVM內(nèi)存空間不足,JVM寧愿拋出OutOfMemoryError運(yùn)行時(shí)錯(cuò)誤(OOM),讓程序異常終止,也不會(huì)靠回收強(qiáng)引用對(duì)象來(lái)解決內(nèi)存不足的問(wèn)題。對(duì)于一個(gè)普通的對(duì)象,如果沒(méi)有其他的引用關(guān)系,只要超過(guò)了引用的作用域或者顯式地將相應(yīng)(強(qiáng))引用賦值為null,就意味著此對(duì)象可以被垃圾收集了。但要注意的是,并不是賦值為null后就立馬被垃圾回收,具體的回收時(shí)機(jī)還是要看垃圾收集策略的。

如Object obj = new Object();

2.軟引用(soft reference)

軟引用相對(duì)強(qiáng)引用要弱化一些,可以讓對(duì)象豁免一些垃圾收集。當(dāng)內(nèi)存空間足夠的時(shí)候,垃圾回收器不會(huì)回收它。只有當(dāng)JVM認(rèn)定內(nèi)存空間不足時(shí)才會(huì)去回收軟引用指向的對(duì)象。JVM會(huì)確保在拋出OOM前清理軟引用指向的對(duì)象,而且JVM是很聰明的,會(huì)盡可能優(yōu)先回收長(zhǎng)時(shí)間閑置不用的軟引用指向的對(duì)象,對(duì)那些剛構(gòu)建的或剛使用過(guò)的軟引用指向的對(duì)象盡可能的保留?;谲浺玫倪@些特性,軟引用可以用來(lái)實(shí)現(xiàn)很多內(nèi)存敏感點(diǎn)的緩存場(chǎng)景,即如果內(nèi)存還有空閑,可以暫時(shí)緩存一些業(yè)務(wù)場(chǎng)景所需的數(shù)據(jù),當(dāng)內(nèi)存不足時(shí)就可以清理掉,等后面再需要時(shí),可以重新獲取并再次緩存。這樣就確保在使用緩存提升性能的同時(shí),不會(huì)導(dǎo)致耗盡內(nèi)存。

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

Object obj = new Object();
SoftReference sf = new SoftReference(obj);
obj = null;
//有時(shí)候會(huì)返回null
sf.get(); 

通過(guò)上面的代碼可以看出sf是對(duì)obj的一個(gè)軟引用,當(dāng)sf對(duì)象還沒(méi)有被銷毀前,sf.get()可以獲取到這個(gè)對(duì)象,如果已被銷毀,則返回null。

正確使用軟引用的示例代碼如下:

SoftReference> ref = new SoftReference>(new LinkedList());
 
// somewhere else in your code, you create a Foo that you want to add to the list
List list = ref.get();
if (list != null)
{
    list.add(foo);
}
else
{
    // list is gone; do whatever is appropriate
} 

在使用軟引用的時(shí)候必須檢查引用是否為null。因?yàn)槔占骺赡茉谌我鈺r(shí)刻回收軟引用,如果不做是否null的判斷,可能會(huì)出現(xiàn)NullPointerException的異常。

3.弱引用(weak reference)

弱引用指向的對(duì)象是一種十分臨近finalize狀態(tài)的情況,當(dāng)弱引用被清除的時(shí)候,就符合finalize的條件了。弱引用與軟引用最大的區(qū)別就是弱引用比軟引用的生命周期更短暫。垃圾回收器會(huì)掃描它所管轄的內(nèi)存區(qū)域的過(guò)程中,只要發(fā)現(xiàn)弱引用的對(duì)象,不管內(nèi)存空間是否有空閑,都會(huì)立刻回收它。如同前面我說(shuō)過(guò)的,具體的回收時(shí)機(jī)還是要看垃圾回收策略的,因此那些弱引用的對(duì)象并不是說(shuō)只要達(dá)到弱引用狀態(tài)就會(huì)立馬被回收。

基于弱引用的這些特性,弱引用同樣可以應(yīng)用在很多需要緩存的場(chǎng)景。

Object obj = new Object();
WeakReference wf = new WeakReference(obj);
obj = null;
//有時(shí)候會(huì)返回null
wf.get();
//返回是否被垃圾回收器標(biāo)記為即將回收的垃圾
wf.isEnQueued();
4.幻象引用(phantom reference)

幻象引用,也有被說(shuō)成是虛引用或幽靈引用。幻象引用并不會(huì)決定對(duì)象的生命周期。即如果一個(gè)對(duì)象僅持有虛引用,就相當(dāng)于沒(méi)有任何引用一樣,在任何時(shí)候都可能被垃圾回收器回收。不能通過(guò)它訪問(wèn)對(duì)象,幻象引用僅僅是提供了一種確保對(duì)象被finalize以后,做某些事情的機(jī)制(如做所謂的Post-Mortem清理機(jī)制),也有人利用幻象引用監(jiān)控對(duì)象的創(chuàng)建和銷毀。

Object obj = new Object();
PhantomReference pf = new PhantomReference(obj);
obj=null;
//永遠(yuǎn)返回null
pf.get();
//返回是否從內(nèi)存中已經(jīng)刪除
pf.isEnQueued(); 

 
幻象引用的get方法永遠(yuǎn)返回null,主要用于檢查對(duì)象是否已經(jīng)從內(nèi)存中刪除。

通過(guò)上面對(duì)四種引用類型的分析,你可能發(fā)現(xiàn)對(duì)象的可達(dá)性是JVM垃圾收集器決定如何處理對(duì)象的一個(gè)重要考慮指標(biāo)。

所有引用類型都是抽象類java.lang.ref.Reference的子類,子類里提供了get()方法。通過(guò)上面的分析中可以得知,除了幻象引用(因?yàn)間et永遠(yuǎn)返回null),如果對(duì)象還沒(méi)有被銷毀,都可以通過(guò)get方法獲取原有對(duì)象。其實(shí)有個(gè)非常關(guān)鍵的注意點(diǎn),利用軟引用和弱引用,我們可以將訪問(wèn)到的對(duì)象,重新指向強(qiáng)引用,也就是人為的改變了對(duì)象的可達(dá)性狀態(tài)。所以對(duì)于軟引用、弱引用之類,垃圾收集器可能會(huì)存在二次確認(rèn)的問(wèn)題,以確保處于弱引用狀態(tài)的對(duì)象沒(méi)有改變?yōu)閺?qiáng)引用。

但是有個(gè)問(wèn)題,如果我們錯(cuò)誤的保持了強(qiáng)引用(比如,賦值給了static變量),那么對(duì)象可能就沒(méi)有機(jī)會(huì)變回類似弱引用的可達(dá)性狀態(tài)了,就會(huì)產(chǎn)生內(nèi)存泄露。所以,檢查弱引用指向?qū)ο笫欠癖焕占?,也是診斷是否有特定內(nèi)存泄露的一個(gè)思路,我們的框架使用到弱引用又懷疑有內(nèi)存泄露,就可以從這個(gè)角度檢查。

對(duì)于軟引用、弱引用、幻象引用可以配合引用隊(duì)列(ReferenceQueue)來(lái)使用,特別是幻象引用,get方法只返回null,如果再不指定引用隊(duì)列,基本就沒(méi)有任何意義了。

上面分析了四種引用類型的使用,熟悉這幾種應(yīng)用類型對(duì)深入理解JVM也大有裨益。

參考:

http://www.kdgregory.com/inde...

極客時(shí)間《Java核心技術(shù)36講》

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/75672.html

相關(guān)文章

  • 金三銀四面試季節(jié)之Java 核心面試技術(shù)點(diǎn) - JVM 小結(jié)

    摘要:直接對(duì)棧的操作只有兩個(gè),就是對(duì)棧幀的壓棧和出棧。中將永久代移除,同時(shí)增加元數(shù)據(jù)區(qū)。在中,本地方法棧和虛擬機(jī)棧是在同一塊兒區(qū)域,這完全取決于技術(shù)實(shí)現(xiàn)的決定,并未在規(guī)范中強(qiáng)制。 原文:https://github.com/linsheng97... 描述一下 JVM 的內(nèi)存區(qū)域 程序計(jì)數(shù)?(PC,Program Counter Register)。在 JVM 規(guī)范中,每個(gè)線程都有它自己的...

    XGBCCC 評(píng)論0 收藏0
  • Java中的四種引用強(qiáng)引用、引用、引用、虛引用

    摘要:在之后,對(duì)引用的概念進(jìn)行了擴(kuò)充,將引用分為強(qiáng)引用軟引用弱引用虛引用種,這種引用強(qiáng)度依次逐漸減弱。軟引用是用來(lái)描述一些還有用但并非必需的對(duì)象。虛引用也稱為幽靈引用或者幻影引用,它是最弱的一種引用關(guān)系。 以下內(nèi)容摘自《深入理解Java虛擬機(jī) JVM高級(jí)特性與最佳實(shí)踐》第2版,強(qiáng)烈推薦沒(méi)有看過(guò)的同學(xué)閱讀,讀完的感覺(jué)就是原來(lái)學(xué)的都是些什么瘠薄東西(╯‵□′)╯︵┴─┴ 在JDK1.2以前,Ja...

    wwolf 評(píng)論0 收藏0
  • 幾分鐘理解 Jdk - Reference

    摘要:一個(gè)對(duì)象是否有虛引用的存在,完全不會(huì)對(duì)其生存時(shí)間構(gòu)成影響,也無(wú)法通過(guò)虛引用來(lái)取得一個(gè)對(duì)象實(shí)例。為一個(gè)對(duì)象設(shè)置虛引用關(guān)聯(lián)的唯一目的就是能在這個(gè)對(duì)象被垃圾收集器回收時(shí)收到一個(gè)系統(tǒng)通知。在之后提供了類來(lái)實(shí)現(xiàn)虛引用參考深入理解虛擬機(jī) GC $TODO$ 一個(gè)對(duì)象的生命周期 一個(gè)對(duì)象的生命周期從它被創(chuàng)建開(kāi)始,此時(shí)虛擬機(jī)會(huì)給它置一個(gè)內(nèi)部標(biāo)識(shí)finalizable,當(dāng) GC 到達(dá)某一個(gè)安全點(diǎn)并檢驗(yàn)該...

    JohnLui 評(píng)論0 收藏0
  • 引用都答不上,憑什么說(shuō)你是Java服務(wù)端開(kāi)發(fā)

    摘要:弱引用弱引用比軟引用更弱,被弱引用關(guān)聯(lián)的對(duì)象只能存活到發(fā)生下一次垃圾回收之前,也就是說(shuō)當(dāng)發(fā)生時(shí),無(wú)論當(dāng)前內(nèi)存是否足夠,都會(huì)被回收掉。這是最終的狀態(tài),不能再變?yōu)槠渌鼱顟B(tài)。如下圖所示對(duì)象都是可被回收的。 【干貨點(diǎn)】看完該篇文章,就基本可以解答面試熱點(diǎn)【談?wù)剬?duì)Java中幾種引用的理解】了。 大家都知道我公眾號(hào)的副業(yè)是 showImg(https://segmentfault.com/img/...

    mozillazg 評(píng)論0 收藏0
  • 深入理解虛擬機(jī)之垃圾回收

    摘要:深入理解虛擬機(jī)高級(jí)特性與最佳實(shí)踐第二版讀書筆記與常見(jiàn)面試題總結(jié)上篇文章傳送門深入理解虛擬機(jī)之內(nèi)存區(qū)域本節(jié)常見(jiàn)面試題推薦帶著問(wèn)題閱讀,問(wèn)題答案在文中都有提到如何判斷對(duì)象是否死亡兩種方法。虛引用主要用來(lái)跟蹤對(duì)象被垃圾回收的活動(dòng)。 《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐(第二版》讀書筆記與常見(jiàn)面試題總結(jié) 上篇文章傳送門: 深入理解虛擬機(jī)之Java內(nèi)存區(qū)域 本節(jié)常見(jiàn)面試題(推薦帶著...

    IamDLY 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<