深入理解java虛擬機-垃圾收集算法

從如何判定對象消亡的角度出發(fā),垃圾收集算法可以劃分為“引用計數(shù)式垃圾收集”和“追蹤式垃圾收集”兩大類,這兩類也被稱為“直接垃圾收集”和“間接垃圾收集”沐祷。

1.分代收集理論

兩個分代假說:

(1)弱分代假說:絕大多數(shù)對象都是朝生夕滅的

(2)強分代假說:熬過越多次垃圾收集過程的對象就越難以消亡

奠定了垃圾收集器的一致設(shè)計原則:

收集器應(yīng)該將java堆劃分出不同的區(qū)域,然后將回收對象依據(jù)其年齡分配到不同的區(qū)域之中存儲。

把java堆劃分為新生代摩窃,老年代兩個區(qū)域。在新生代中每次垃圾收集時都發(fā)現(xiàn)有大批對象死去芬骄,而每次回收后存活的少量對象猾愿,將會逐步晉升到老年代中存放。

分代收集并非只是簡單劃分一下內(nèi)存區(qū)域那么容易账阻,它至少存在一個明顯的困難:對象不是孤立的蒂秘,對象之間會存在跨代引用。假如要現(xiàn)在進行一次只局限于新生代區(qū)域內(nèi)的收集淘太,但新生代中的對象完全有可能被老年代所引用姻僧,為了找出該區(qū)域的存活對象观挎,不得不在固定的GCRoots之外,再額外遍歷整個老年代中所有對象來確倍位可達(dá)性分析結(jié)果的正確性,反過來也是一樣造成。為了解決這個問題显熏,就需要對分代收集理論添加第三條經(jīng)驗法則:

(3)跨代引用假說:跨代引用相對于同代引用來說僅占極少數(shù)。

即存在相互引用關(guān)系的兩個對象是應(yīng)該傾向于同時生存或者同時消亡的晒屎。比如:如果某個新生代對象存在跨代引用喘蟆,由于老年代對象難以消亡,該引用會使得新生代對象在收集時同樣得以存活鼓鲁,進而隨著年齡增長之后晉升到老年代中蕴轨,這是跨代引用也隨機被消除了。

依據(jù)這條假說骇吭,我們只需在新生代上建立一個全局的數(shù)據(jù)結(jié)構(gòu)橙弱,把老年代劃分為若干小塊,標(biāo)識出老年代的哪一塊內(nèi)存會存在跨代引用燥狰。此后當(dāng)發(fā)生新生代區(qū)域收集時棘脐,只有包含了跨代引用的小塊內(nèi)存里的對象才會被加入到GC Roots進行掃描。

2.標(biāo)記-清除算法

算法分為“標(biāo)記”和“清除”兩個階段:首先標(biāo)記出所有需要回收的對象龙致,在標(biāo)記完成后蛀缝,統(tǒng)一回收掉所有被標(biāo)記的對象,也可以反過來目代,標(biāo)記存活的對象屈梁,回收所有未被標(biāo)記的對象。標(biāo)記過程就是對象是否處于垃圾的判定過程榛了。

標(biāo)記-清除算法缺點:

1.執(zhí)行效率不穩(wěn)定在讶,如果java堆中包含大量對象,而且其中大部分是需要被回收的忽冻,這時必須進行大量標(biāo)記和清除動作真朗,導(dǎo)致標(biāo)記和清除兩個過程的執(zhí)行效率都隨著對象數(shù)量增長而降低;

2.內(nèi)存空間碎片化問題僧诚,標(biāo)記遮婶,清除之后會產(chǎn)生大量不連續(xù)的內(nèi)存碎片,空間碎片太多可能會導(dǎo)致以后在程序運行過程中需要分配較大對象時無法找到足夠的連續(xù)內(nèi)存而不得不提前觸發(fā)另一次垃圾收集動作湖笨。

3.標(biāo)記-復(fù)制算法

為了解決標(biāo)記-清除算法面對大量可回收對象時執(zhí)行效率低的問題旗扑,F(xiàn)enichel提出了一種稱為半?yún)^(qū)復(fù)制垃圾收集算法,它將可用內(nèi)存容量劃分為大小相等的兩塊慈省,每次只使用其中的一塊臀防。當(dāng)這一塊內(nèi)存用完了,就將還存活著的對象復(fù)制到另外一塊上面,然后再把已使用過的內(nèi)存空間一次性清理掉袱衷。如果內(nèi)存中多數(shù)對象都是存活的捎废,這種算法將會產(chǎn)生大量的內(nèi)存空間開銷,但對于多數(shù)對象都是可回收的情況致燥,算法需要復(fù)制的就是占少數(shù)的存活對象登疗,而且每次都是針對整個半?yún)^(qū)進行內(nèi)存回收,分配內(nèi)存時就不用了考慮空間碎片的復(fù)雜情況嫌蚤,只要移動堆頂指針辐益,按順序分配即可。

缺點:

這種復(fù)制回收算法的代價是將可用內(nèi)存縮小為原來的一半脱吱,空間浪費太多智政。

Andrew Appel針對具備“朝生夕滅”特點的對象,提出了一種更優(yōu)化的半?yún)^(qū)復(fù)制分代策略箱蝠,現(xiàn)在稱為“Appel式回收”续捂。

具體做法:把新生代分為一塊較大的Eden空間和兩塊較小的Survivor空間,每次分配只使用Eden和其中一塊Survivor宦搬。發(fā)生垃圾收集時疾忍,將Eden和Survivor中仍然存活的對象一次性復(fù)制到另外一塊Survivor空間上,然后直接清理掉Eden和已經(jīng)用過的那塊Survivor空間床三。Eden和Survivor的大小比例是8:1一罩,每次新生代中可用內(nèi)存空間為整個新生代容量的90%,只有一個Survivor空間是被“浪費的”撇簿。任何人都沒有辦法保證每次回收只有不多于10%的對象存活聂渊,當(dāng)Survivor空間不足以容納一次MinorGC之后的存活的對象時,就需要依賴其他內(nèi)存區(qū)域進行分配擔(dān)保四瘫。如果另一塊Survivor空間沒有足夠空間存放上一次新生代收集下來的存活對象汉嗽,這些對象便將通過分配擔(dān)保機制直接進入老年代,這對虛擬機來說就是安全的找蜜。

4.標(biāo)記-整理算法

標(biāo)記-復(fù)制算法在對象存活率較高時就要進行較多的復(fù)制操作饼暑,效率將會降低。如果不想浪費50%的空間洗做,就需要額外的空間進行復(fù)制擔(dān)保弓叛,以應(yīng)對內(nèi)存中所有對象都100%存活的極端情況,所以老年代一般不能直接選用這種算法诚纸。

標(biāo)記過程仍然與“標(biāo)記-清除”算法一樣撰筷,讓所有存活的對象都向內(nèi)存空間一端移動,然后直接清理掉邊界以外的內(nèi)存畦徘。標(biāo)記清除算法與標(biāo)記整理算法的本質(zhì)差異在于前者是一種非移動式的回收算法毕籽,而后者是移動式的抬闯。

如果移動存活對象,尤其是在老年代這種每次回收都有大量對象存活區(qū)域关筒,移動存活對象并更新所有引用這些對象的地方將會是一種極為負(fù)重的操作溶握,而且這種對象移動操作必須全程暫停用戶應(yīng)用程序才能進行。

但如果跟標(biāo)記清除算法那樣完全不考慮移動和整理存活對象的話蒸播,彌散于堆中的存活對象導(dǎo)致的空間碎片化問題就只能依賴于更為復(fù)雜的內(nèi)存分配器和內(nèi)存訪問器來解決奈虾。譬如通過“分區(qū)空閑分配鏈表”來解決內(nèi)存分配問題。

基于以上兩點廉赔,是否移動對象都存在弊端,移動則內(nèi)存回收時會更復(fù)雜匾鸥,不移動則內(nèi)存分配時會更復(fù)雜蜡塌。從垃圾收集的停頓時間來看,不移動對象停頓時間更短勿负,甚至不需要停頓馏艾,但從整個程序的吞吐量來看,移動對象會更劃算奴愉。

還有一種做法“和稀泥式”解決方案可以不在內(nèi)存分配和訪問上增加太大額外負(fù)擔(dān)琅摩。做法是讓虛擬機平時大多數(shù)時間都采用標(biāo)記-清除算法,暫時容忍內(nèi)存碎片的存在锭硼,直到內(nèi)存空間的碎片化程度已經(jīng)達(dá)到影響對象分配時房资,再采用標(biāo)記-整理算法收集一次,以獲得規(guī)整的內(nèi)存空間檀头。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末轰异,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子暑始,更是在濱河造成了極大的恐慌搭独,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件廊镜,死亡現(xiàn)場離奇詭異牙肝,居然都是意外死亡,警方通過查閱死者的電腦和手機嗤朴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門配椭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人雹姊,你說我怎么就攤上這事颂郎。” “怎么了容为?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵乓序,是天一觀的道長寺酪。 經(jīng)常有香客問我,道長替劈,這世上最難降的妖魔是什么寄雀? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮陨献,結(jié)果婚禮上盒犹,老公的妹妹穿的比我還像新娘。我一直安慰自己眨业,他們只是感情好急膀,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著龄捡,像睡著了一般卓嫂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上聘殖,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天晨雳,我揣著相機與錄音,去河邊找鬼奸腺。 笑死餐禁,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的突照。 我是一名探鬼主播帮非,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼讹蘑!你這毒婦竟也來了喜鼓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤衔肢,失蹤者是張志新(化名)和其女友劉穎庄岖,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體角骤,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡傻挂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年蒿辙,在試婚紗的時候發(fā)現(xiàn)自己被綠了管毙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片关拒。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蝉揍,靈堂內(nèi)的尸體忽然破棺而出链峭,到底是詐尸還是另有隱情,我是刑警寧澤又沾,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布弊仪,位于F島的核電站熙卡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏励饵。R本人自食惡果不足惜驳癌,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望役听。 院中可真熱鬧颓鲜,春花似錦、人聲如沸典予。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瘤袖。三九已至衣摩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間孽椰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工凛篙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留黍匾,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓呛梆,卻偏偏與公主長得像锐涯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子填物,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

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

  • 這篇文章將講解垃圾回收的概念以及對那些區(qū)域進行垃圾回收纹腌,最后講解幾種常見的垃圾回收算法。 概述 什么叫垃圾收集器滞磺?...
    Michaelhbjian閱讀 188評論 0 0
  • 概述 說到垃圾收集(Garbage Collection升薯,GC),大部分人都會把這項技術(shù)當(dāng)做 Java 語言的伴生...
    FX_SKY閱讀 270評論 0 2
  • 表情是什么击困,我認(rèn)為表情就是表現(xiàn)出來的情緒涎劈。表情可以傳達(dá)很多信息。高興了當(dāng)然就笑了阅茶,難過就哭了蛛枚。兩者是相互影響密不可...
    Persistenc_6aea閱讀 124,413評論 2 7
  • 16宿命:用概率思維提高你的勝算 以前的我是風(fēng)險厭惡者,不喜歡去冒險脸哀,但是人生放棄了冒險蹦浦,也就放棄了無數(shù)的可能。 ...
    yichen大刀閱讀 6,037評論 0 4