關(guān)于Java引用,你必須知道這些

引用

Java 虛擬機(jī)接管了所有的內(nèi)存分配與回收工作拴疤,極大地減少了程序員的工作量和錯(cuò)誤率。GC 在回收內(nèi)存時(shí)独泞,通常采用被稱為可達(dá)性分析的算法判斷一個(gè)對(duì)象是否可以回收呐矾。而在可達(dá)性分析中,對(duì)象的引用有著決定性的作用懦砂。在下圖中蜒犯,GC 從 GC Roots 開(kāi)始順著引用鏈往下尋找對(duì)象,發(fā)現(xiàn)當(dāng)前有引用的對(duì)象為object 1荞膘、object 2罚随、object 3、object 4羽资,而object 5淘菩、object 6、object 7雖然互相之間有引用但已經(jīng)無(wú)法從外部引用到削罩。因此瞄勾,圖中 object 1-4 為存活的對(duì)象,而 object 5-7 為可回收的對(duì)象弥激。

雖然 GC 能夠完成垃圾收集工作进陡,但是仍然無(wú)法避免 out of memory 。一方面在開(kāi)發(fā)過(guò)程中需要注意不再使用的引用設(shè)為 null 來(lái)釋放引用的對(duì)象微服,另一方面也需要從對(duì)象引用的角度考慮使用合適的引用類型更好地管理對(duì)象內(nèi)存趾疚。

可達(dá)性分析


引用的類型

Java 有4種類型的引用:strong(強(qiáng)引用),soft(軟引用)以蕴,weak(弱引用)和 phantom(虛引用)糙麦。

強(qiáng)引用:強(qiáng)引用是在 Java 中的普通引用。任何時(shí)候我們創(chuàng)建一個(gè)新的對(duì)象丛肮,默認(rèn)情況下創(chuàng)建一個(gè)強(qiáng)引用赡磅。例如類的靜態(tài)變量,從類被初始化之后便已經(jīng)分配內(nèi)存宝与,作為強(qiáng)引用對(duì)象不能被 GC 回收焚廊,需要等待虛擬機(jī)退出或類被卸載才能釋放引用被 GC 回收冶匹。

弱引用:弱引用無(wú)法保證對(duì)象一定存活于內(nèi)存中,被弱引用關(guān)聯(lián)的對(duì)象只能生存到下一次垃圾收集發(fā)生之前咆瘟。我們可以使用 WeakReference 類來(lái)實(shí)現(xiàn)弱引用嚼隘。

弱引用

軟引用:軟引用比弱引用稍強(qiáng)一點(diǎn),垃圾收集發(fā)生時(shí)弱引用一定會(huì)被回收袒餐,而軟引用會(huì)請(qǐng)求 GC 保留自己除非沒(méi)有其他選擇飞蛹,可以理解為只在將要發(fā)生內(nèi)存溢出時(shí) GC 才會(huì)回收軟引用。我們可以使用 SoftReference 類來(lái)實(shí)現(xiàn)軟引用灸眼。

軟引用

虛引用:一個(gè)對(duì)象是否有虛引用的存在卧檐,完全不會(huì)對(duì)其生存時(shí)間構(gòu)成影響,也無(wú)法通過(guò)虛引用來(lái)取得一個(gè)對(duì)象實(shí)例幢炸。為一個(gè)對(duì)象設(shè)置虛引用關(guān)聯(lián)的唯一目的就是能在這個(gè)對(duì)象被 GC 回收時(shí)收到一個(gè)系統(tǒng)通知泄隔。我們可以使用 PhantomReference 類來(lái)實(shí)現(xiàn)虛引用。當(dāng) GC 準(zhǔn)備回收一個(gè)對(duì)象時(shí)宛徊,如果發(fā)現(xiàn)它還有虛引用,就會(huì)在回收對(duì)象的內(nèi)存之前逻澳,把這個(gè)虛引用加入到與之關(guān)聯(lián)的引用隊(duì)列中闸天。開(kāi)發(fā)者可以通過(guò)判斷引用隊(duì)列中是否包含對(duì)象來(lái)判斷對(duì)象是否即將被回收,可以在回收之前做些處理斜做。

虛引用

引用隊(duì)列:如果引用關(guān)聯(lián)了引用隊(duì)列苞氮,則 GC 回收對(duì)象內(nèi)存的時(shí)候會(huì)把引用加入到引用隊(duì)列中。當(dāng)引用隊(duì)列中包含引用時(shí)瓤逼,意味著引用指向的堆內(nèi)存中的對(duì)象被回收笼吟。

引用隊(duì)列

引用的應(yīng)用

構(gòu)建緩存

使用軟引用可以用于創(chuàng)建 Java 本地高速緩存,只要內(nèi)存仍然夠用緩存就不會(huì)被刪除霸旗,而一旦內(nèi)存緊張即將溢出時(shí)贷帮,GC 會(huì)刪除部分緩存釋放內(nèi)存。例如诱告,創(chuàng)建比較耗時(shí)影響性能的數(shù)據(jù)對(duì)象撵枢、一段時(shí)間內(nèi)可以重復(fù)使用的資源、不常變化的數(shù)據(jù)等精居,都可以使用軟引用構(gòu)建緩存锄禽,既能保證讀取性能,又不會(huì)導(dǎo)致內(nèi)存溢出靴姿。

WeakHashMap

WeakHashMap 是以弱引用鍵實(shí)現(xiàn)的哈希表沃但。當(dāng) WeakHashMap 中的鍵不再被強(qiáng)引用使用時(shí),GC 下次回收垃圾時(shí)將回收此鍵佛吓。WeakHashMap 中的鍵被回收后宵晚,哈希表的條目也會(huì)被 GC 回收垂攘。因此,WeakHashMap 可以用于臨時(shí)存儲(chǔ)一些不需要長(zhǎng)時(shí)間使用的對(duì)象坝疼,可以有效避免內(nèi)存溢出搜贤。

WeakHashMap

總結(jié)

Java 開(kāi)發(fā)中最常用的引用是強(qiáng)引用,通過(guò)new創(chuàng)建對(duì)象得到強(qiáng)引用钝凶。強(qiáng)引用會(huì)阻止 GC 釋放對(duì)象內(nèi)存仪芒,長(zhǎng)時(shí)間運(yùn)行容易導(dǎo)致內(nèi)存溢出。在開(kāi)發(fā)中耕陷,對(duì)于強(qiáng)引用變量在使用完畢后應(yīng)把值設(shè)置為 null 來(lái)幫助 GC 進(jìn)行垃圾回收掂名。在 Java 中還有另外三種引用類型,弱引用哟沫、軟引用和虛引用饺蔑。弱引用和軟引用可以用于構(gòu)建緩存和避免內(nèi)存泄露,虛引用可以用于獲知對(duì)象將被回收的通知并進(jìn)行處理嗜诀。

四種引用類型的對(duì)比如下:

四種引用類型的對(duì)比
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末猾警,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子隆敢,更是在濱河造成了極大的恐慌发皿,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拂蝎,死亡現(xiàn)場(chǎng)離奇詭異穴墅,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)温自,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門玄货,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人悼泌,你說(shuō)我怎么就攤上這事松捉。” “怎么了券躁?”我有些...
    開(kāi)封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵惩坑,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我也拜,道長(zhǎng)以舒,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任慢哈,我火速辦了婚禮蔓钟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘卵贱。我一直安慰自己滥沫,他們只是感情好侣集,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著兰绣,像睡著了一般世分。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上缀辩,一...
    開(kāi)封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天臭埋,我揣著相機(jī)與錄音,去河邊找鬼臀玄。 笑死瓢阴,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的健无。 我是一名探鬼主播荣恐,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼累贤!你這毒婦竟也來(lái)了叠穆?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤臼膏,失蹤者是張志新(化名)和其女友劉穎痹束,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體讶请,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年屎媳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了夺溢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡烛谊,死狀恐怖风响,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情丹禀,我是刑警寧澤状勤,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站双泪,受9級(jí)特大地震影響持搜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜焙矛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一葫盼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧村斟,春花似錦贫导、人聲如沸抛猫。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)闺金。三九已至,卻和暖如春峰档,著一層夾襖步出監(jiān)牢的瞬間败匹,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工面哥, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留哎壳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓尚卫,卻偏偏與公主長(zhǎng)得像归榕,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子吱涉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容