Java 對(duì)象之死

我們都知道垃圾回收是指回收那些不再使用的對(duì)象所占的內(nèi)存區(qū)域锁施。生動(dòng)的說挑胸,在 Java 的世界里,無用的人就要拉出去槍斃了夷狰,并且把其所占的地盤清理岭皂,以便讓“別人“來使用。

Java對(duì)象之死

如何判斷對(duì)象“無用”孵淘?

關(guān)于判斷對(duì)象是否無用的算法蒲障,在JVM的發(fā)展過程中出現(xiàn)過兩種算法:一種是引用計(jì)數(shù)和根集算法。

引用計(jì)數(shù)算法

例如下圖中的object1的引用計(jì)數(shù)是2瘫证,GC的時(shí)候不回收揉阎,object6、object7引用計(jì)數(shù)為0背捌,GC的時(shí)候要被回收毙籽。引用計(jì)數(shù)有個(gè)缺點(diǎn):當(dāng)引用產(chǎn)生閉環(huán)的時(shí)候即便是對(duì)象實(shí)際上已經(jīng)“無用”也無法回收了,例如下圖中的 毡庆,object4坑赡、object5、object8直接引用關(guān)系么抗。

引用計(jì)數(shù)算法

根集算法

引用計(jì)數(shù)算法簡高效毅否,早期的 Java 虛擬機(jī)中使用這個(gè)方式,但是正如上面提到的不能解決“引用閉環(huán)”的問題蝇刀,后來的 Java 虛擬機(jī)中普普采用根集算法螟加。從 GCRoot(比如一個(gè)靜態(tài)變量) 開始遍歷引用關(guān)系,能遍歷到的吞琐,叫做引用可達(dá)捆探,遍歷不到的叫做不可達(dá)。不可達(dá)的對(duì)象就被判“死刑了”站粟,GC的時(shí)候?qū)⒈粯寯赖簟?/p>

根集算法

對(duì)象回收之后的內(nèi)存如何處置黍图?

人死了、遺產(chǎn)處理不好會(huì)產(chǎn)生很多糾紛奴烙,所以有法律制度助被。在 JVM 的世界里對(duì)象死了剖张,剩下的“遺產(chǎn)”無非就是它占據(jù)的那片內(nèi)存空間。對(duì)象死后生下的那部分內(nèi)存空間進(jìn)行一下規(guī)劃的恰起,具體算法有三種修械。

三種回收算法.png

標(biāo)記-清除

標(biāo)記就是把那些“無用的對(duì)象”標(biāo)記一下,被標(biāo)記的對(duì)象等于被判了死刑检盼,也就是就可以回收了,清除就是變那些被標(biāo)記了的對(duì)象清楚掉翘单。

GC標(biāo)記之后的狀態(tài)
清除之后的狀態(tài)

我們發(fā)現(xiàn)吨枉,清除之后的狀態(tài),其中的可用內(nèi)存并不是連續(xù)的哄芜,也就是說內(nèi)存存在碎片貌亭,如果創(chuàng)建一個(gè)大對(duì)象,無法分配到足夠大的連續(xù)內(nèi)存空間认臊,使得GC不得不做一次重新整理圃庭。由于可用對(duì)象和無用對(duì)象直接的內(nèi)存不是連續(xù)的,所以標(biāo)記的過程是要遍歷識(shí)別內(nèi)存區(qū)域的失晴,清除的過程也是要遍歷識(shí)別的剧腻,整個(gè)過程效率比較低。

標(biāo)記-復(fù)制

標(biāo)記的過程不變涂屁。把內(nèi)存劃分為兩部分书在,一部分叫做預(yù)留區(qū)域(下圖虛線框中),不分配對(duì)象拆又。在GC的時(shí)候把那些正在使用的對(duì)象復(fù)制到預(yù)留區(qū)域儒旬,然后再把非預(yù)留區(qū)域以外的內(nèi)存全部清除。

標(biāo)記之后內(nèi)存狀態(tài)
復(fù)制之后內(nèi)存狀態(tài)
清除之后內(nèi)存狀體

解決了效率和內(nèi)存碎片的問題帖族,但是代價(jià)是昂貴的:犧牲了1/2的內(nèi)存栈源,顯然在很多情況下是無法接受的。

標(biāo)記-整理

標(biāo)記的過程依然不變竖般,標(biāo)記之后處于內(nèi)存末端區(qū)域的正在使用的對(duì)象向前移動(dòng)占據(jù)覆蓋那些被標(biāo)記了的區(qū)域(有一種碾壓的感覺)甚垦,把正在使用的對(duì)象趕到一起,再把剩余的標(biāo)記對(duì)象全部清除捻激。

標(biāo)記之后內(nèi)存狀體
移動(dòng)之后的內(nèi)存狀態(tài)
清除之后內(nèi)存狀體

分代混合算法

在現(xiàn)代虛擬機(jī)(通常就是 HotSpot(TM))制轰,使用的分代算法來處理內(nèi)存,并沒有什么新意胞谭,只是針對(duì)對(duì)象的生命周期范圍來劃分區(qū)域垃杖,不同的區(qū)域使用不同的算法。一般分為新生代和老生代丈屹,新生代由于生命不長调俘,GC的時(shí)候大部分對(duì)象已經(jīng)死亡伶棒,所以有足夠的空間作為擔(dān)保,可用使用標(biāo)記-復(fù)制算法彩库,對(duì)于老生代老生代使用標(biāo)記-清除或標(biāo)記-整理算法肤无。

分代混合算法
分代混合算法

Stop the world

抬腳打掃衛(wèi)生.png

想象一下,你不可能在媽媽一邊打掃衛(wèi)生的時(shí)候你一邊扔垃圾吧骇钦,她當(dāng)然希望你乖乖做在沙發(fā)上抬起腳來別動(dòng)宛渐。JVM的世界亦如此,前面我們說道使用引用關(guān)系的根集算法來標(biāo)記對(duì)象是否無用眯搭,二這個(gè)引用關(guān)系只是某一時(shí)刻的“快照”窥翩,使用一個(gè)叫做OopMap的數(shù)據(jù)結(jié)構(gòu)來保存的。引用關(guān)系是會(huì)隨時(shí)間變化的鳞仙,所以在垃圾回收器進(jìn)行垃圾回收時(shí)候就必須的有所停頓寇蚊,sun把這個(gè)現(xiàn)象叫做“Stop the world ”。

所以頻繁的GC會(huì)影響性能棍好,對(duì)象存活時(shí)間過長會(huì)占用內(nèi)存仗岸,在實(shí)際開發(fā)過程中我們?nèi)绾稳テ胶鈨?nèi)存空間和執(zhí)行效率、如何去選擇對(duì)象生命周期是非常重要的借笙。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末扒怖,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子提澎,更是在濱河造成了極大的恐慌姚垃,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盼忌,死亡現(xiàn)場離奇詭異积糯,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)谦纱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門看成,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人跨嘉,你說我怎么就攤上這事川慌。” “怎么了祠乃?”我有些...
    開封第一講書人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵梦重,是天一觀的道長。 經(jīng)常有香客問我亮瓷,道長琴拧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任嘱支,我火速辦了婚禮蚓胸,結(jié)果婚禮上挣饥,老公的妹妹穿的比我還像新娘。我一直安慰自己沛膳,他們只是感情好扔枫,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著锹安,像睡著了一般短荐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上八毯,一...
    開封第一講書人閱讀 49,079評(píng)論 1 285
  • 那天搓侄,我揣著相機(jī)與錄音,去河邊找鬼话速。 笑死,一個(gè)胖子當(dāng)著我的面吹牛芯侥,可吹牛的內(nèi)容都是我干的泊交。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼柱查,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼廓俭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起唉工,我...
    開封第一講書人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤研乒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后淋硝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雹熬,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年谣膳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了竿报。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡继谚,死狀恐怖烈菌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情花履,我是刑警寧澤芽世,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站诡壁,受9級(jí)特大地震影響济瓢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜欢峰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一葬荷、第九天 我趴在偏房一處隱蔽的房頂上張望涨共。 院中可真熱鬧,春花似錦宠漩、人聲如沸举反。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽火鼻。三九已至,卻和暖如春雕崩,著一層夾襖步出監(jiān)牢的瞬間魁索,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來泰國打工盼铁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留粗蔚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓饶火,卻偏偏與公主長得像鹏控,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子肤寝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

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

  • 1.什么是垃圾回收当辐? 垃圾回收(Garbage Collection)是Java虛擬機(jī)(JVM)垃圾回收器提供...
    簡欲明心閱讀 89,398評(píng)論 17 311
  • JVM架構(gòu) 當(dāng)一個(gè)程序啟動(dòng)之前,它的class會(huì)被類裝載器裝入方法區(qū)(Permanent區(qū))鲤看,執(zhí)行引擎讀取方法區(qū)的...
    cocohaifang閱讀 1,648評(píng)論 0 7
  • 一. 垃圾回收的意義 在C++中缘揪,對(duì)象所占的內(nèi)存在程序結(jié)束運(yùn)行之前一直被占用,在明確釋放之前不能分配給其它對(duì)...
    Stan_Z閱讀 1,921評(píng)論 0 25
  • 原文閱讀 前言 這段時(shí)間懈怠了义桂,罪過找筝! 最近看到有同事也開始用上了微信公眾號(hào)寫博客了,挺好的~給他們點(diǎn)贊澡刹,這博客我...
    碼農(nóng)戲碼閱讀 5,948評(píng)論 2 31
  • 通過這篇文章你能知道的問題: 1.如何判斷對(duì)象是活著還是死去呻征? 2.在Java語言中,可作為GCRoots的對(duì)象有...
    beneke閱讀 1,351評(píng)論 0 1