垃圾回收算法

  • 標(biāo)記 - 清除算法
  • 復(fù)制算法
  • 標(biāo)記 - 整理算法
  • 分代收集算法

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

實現(xiàn)原理

  • 標(biāo)記出所有需要回收的對象蟀给。
  • 統(tǒng)一回收所有被標(biāo)記的對象黎做。

特點

  • 標(biāo)記和清除效率不高。
  • 產(chǎn)生大量不連續(xù)的內(nèi)存碎片松忍。
  • 標(biāo)記清除算法是最基礎(chǔ)的收集算法蒸殿,后面的幾種算法都是基于這種思路并對其不足進(jìn)行改進(jìn)而得到的。 算法分為“標(biāo)記”和“清除”兩個階段鸣峭。
  • 標(biāo)記 : 首先標(biāo)記處所有需要回收的對象宏所,在標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對象。標(biāo)記的判定就是通過可達(dá)性分析算法分析出可回收對象摊溶。
  • 清除 : 標(biāo)記完成后會回收對象爬骤。但是這其中存在著兩個不足問題 : 第一是標(biāo)記和清除這兩個過程效率不高。其次是清除之后會產(chǎn)生大量不連續(xù)的內(nèi)存碎片莫换。
  • 清除 : 標(biāo)記完成后會回收對象霞玄。
  • 但是這其中存在著兩個不足問題 : 第一是標(biāo)記和清除這兩個過程效率不高。其次是清除之后會產(chǎn)生大量不連續(xù)的內(nèi)存碎片拉岁。
  • 空間碎片太多可能會導(dǎo)致以后在程序運行過程中需要分配比較大對象時坷剧,無法找到足夠連續(xù)內(nèi)存。從而提前觸發(fā)依次GC喊暖。
160f7b667fa1cd3b.png
  • 相當(dāng)于生活中標(biāo)記不需要的物品惫企,然后找?guī)讉€人把這些東西丟了。 但是由于房間的空間是有限的陵叽,如果一直沒有整理房間狞尔,如果有大件家具搬進(jìn)來時丛版,沒有足夠的空間可能要再標(biāo)記清除一下不需要的物品,如果還是沒有辦法放下這件大家具偏序,拋出OOM異常页畦。丟(Out)到(Of)門外(Memory)。

2 復(fù)制算法

實現(xiàn)原理

  • 將內(nèi)存劃分為大小相等的兩塊禽车。
  • 一塊內(nèi)存用完之后復(fù)制存活對象至另一塊寇漫。
  • 清理另一塊內(nèi)存。

特點

  • 實現(xiàn)簡單殉摔,運行高效州胳。
  • 浪費一半空間,代價大逸月。
  • 為了解決效率問題栓撞,復(fù)制收集算法出現(xiàn)了,它將可用內(nèi)存按容量劃分為大小相等的兩塊碗硬,每次只使用其中的一塊瓤湘。
  • 當(dāng)這一塊的內(nèi)存用完了,就將還存活的對象復(fù)制到另一塊上面恩尾,然后把已使用過的那一塊內(nèi)存空間全部清理弛说。
  • 這樣便不用考慮內(nèi)存碎片問題,只要移動堆頂指針翰意,重新按順序分配內(nèi)存即可木人,實現(xiàn)簡單,運行高效冀偶。
  • 只是這種算法的代價是將活動使用的內(nèi)存縮小為原來的一半醒第。
160f7b667fa1cd3b.png
  • 復(fù)制算法當(dāng)存活對象越少(或者垃圾很容易產(chǎn)生)時,它的效率越高进鸠。
    也就是你只要將一些少量需要用到的對象丟到另一片干凈的內(nèi)存中稠曼,就可以輕松的大掃除。

換句話說客年,如果你需要保留的對象很多霞幅,那么便需要又費力又頻繁的搬動到另一塊內(nèi)存中。

  • 復(fù)制收集算法在對象存活率較高時就要進(jìn)行較多的操作搀罢,效率就會變得很低蝗岖。并且只能使用50%的空間。

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

實現(xiàn)原理

  • 標(biāo)記過程與 ”標(biāo)記-清除“ 算法一樣榔至。
  • 存活對象往一端進(jìn)行移動抵赢。
  • 清理其余內(nèi)存。

特點

  • 避免 ”標(biāo)記-清除” 算法導(dǎo)致的內(nèi)存碎片。
  • 避免復(fù)制算法的空間浪費铅鲤。
  • 標(biāo)記 : 因為存活的對象比較多划提,我們將這些對象標(biāo)記起來。然后接下來整理到一塊邢享。
  • 整理 : 讓所有標(biāo)記過的對象都向一端移動鹏往,然后直接清理掉端邊界以外的內(nèi)存。(按內(nèi)存地址一次排列)
160f7b66a84fa47a.png

4 分代收集算法

特點

  • 結(jié)合多種收集算法的優(yōu)勢骇塘。
  • 新生代對象存活率低 => “復(fù)制” 算法(注意這里每一次的復(fù)制比例都是可以調(diào)整的伊履,如一次僅復(fù)制 30% 的存活對象)。
  • 老年代對象存活率高 => “標(biāo)記-整理” 算法款违。

當(dāng)前很多商業(yè)虛擬機(jī)都采用分代收集(Generational Collection)算法作為垃圾收集器唐瀑。

  • 這種算法只是根據(jù)對象存活周期的不同將內(nèi)存劃分為幾塊,進(jìn)而采用不同的回收算法的策略插爹。
  • 一般是把Java堆分成新生代和老年代哄辣。
  • 新生代 : 對象朝生暮死,存活的對象少赠尾,可回收對象多力穗。
    選用復(fù)制算法,只要付出少量存活對象的復(fù)制成本就可以完成收集气嫁。
  • 老年代 : 對象存活率高当窗,回收的對象很少。
    選用標(biāo)記 - 清理算法寸宵,或者標(biāo)記 - 整理算法來進(jìn)行回收超全。
  • 對于新生代采取復(fù)制算法,因為新生代中每次垃圾回收都要回收大部分對象邓馒,也就是說需要復(fù)制的操作次數(shù)較少,采用復(fù)制算法效率最高蛾坯。
  • 但實際中并不是按照上面算法中說的1:1的比例來劃分新生代的空間的光酣,而是將新生代劃分為一塊較大的Eden空間和兩塊較小的Survivor空間,比例為8:1:1(比例可以調(diào)整)脉课。
  • 每次使用Eden和其中一塊Survivor救军,當(dāng)回收時,將Eden和剛才用過的Survivor空間中還存活的對象一次性的復(fù)制到另一塊Survivor空間上倘零,最后清理掉Eden和剛才用過的Survivor空間唱遭。(后面會繼續(xù)研究,如果這次復(fù)制的對象大小超過Survivor空間呈驶,將會有分配擔(dān)保機(jī)制拷泽。)
  • 由于老年代的特點是每次回收都只回收少量對象,使用的是標(biāo)記 - 清理算法,或者標(biāo)記 - 整理算法來進(jìn)行回收司致。它與新生代的比例為 2(老年代) : 1(新生代)拆吆。當(dāng)然這個比例也是可以調(diào)整的。
160f7b66a6600310.png

分代收集算法工作流程

  • 1 . 分配了一個又一個對象 : 放到Eden區(qū)脂矫。
  • 2 . 不好枣耀,Eden區(qū)滿了,只能GC(新生代GC:Minor GC)了 : 把Eden區(qū)的存活對象copy到Survivor A區(qū)庭再,然后清空Eden區(qū)(本來Survivor B區(qū)也需要清空的捞奕,不過本來就是空的)
  • 3 . 又分配了一個又一個對象 : 放到Eden區(qū)。
  • 4 . 不好拄轻,Eden區(qū)滿了颅围,只能GC(新生代GC:Minor GC)了 : 把Eden區(qū)和Survivor A區(qū)的存活對象copy到Survivor B區(qū),然后清空Eden區(qū)和Survivor A區(qū)哺眯。
  • 5 . 又分配了一個又一個對象 : 放到Eden區(qū)谷浅。
  • 6 . 不好,Eden區(qū)滿了奶卓,只能GC(新生代GC:Minor GC)了 : 把Eden區(qū)和Survivor B區(qū)的存活對象copy到Survivor A區(qū)一疯,然后清空Eden區(qū)和Survivor B區(qū)
    為什么不是一塊Survivor空間而是兩塊?
  • 這里涉及到一個新生代和老年代的存活周期的問題夺姑,比如一個對象在新生代經(jīng)歷15次(僅供參考)GC墩邀,就可以移到老年代了。問題來了盏浙,當(dāng)我們第一次GC的時候眉睹,我們可以把Eden區(qū)的存活對象放到Survivor A空間,但是第二次GC的時候废膘,Survivor A空間的存活對象也需要再次用Copying算法竹海,放到Survivor B空間上,而把剛剛的Survivor A空間和Eden空間清除丐黄。第三次GC時斋配,又把Survivor B空間的存活對象復(fù)制到Survivor A空間,如此反復(fù)灌闺。 所以艰争,這里就需要兩塊Survivor空間來回倒騰。

為什么Eden空間這么大而Survivor空間要分的少一點桂对?

  • 新創(chuàng)建的對象都是放在Eden空間甩卓,這是很頻繁的,尤其是大量的局部變量產(chǎn)生的臨時對象蕉斜,這些對象絕大部分都應(yīng)該馬上被回收逾柿,能存活下來被轉(zhuǎn)移到survivor空間的往往不多缀棍。所以,設(shè)置較大的Eden空間和較小的Survivor空間是合理的鹿寻,大大提高了內(nèi)存的使用率睦柴,緩解了Copying算法的缺點。
    我看8:1:1就挺好的毡熏,當(dāng)然這個比例是可以調(diào)整的坦敌,包括上面的新生代和老年代的1:2的比例也是可以調(diào)整的。
    新的問題又來了痢法,從Eden空間往Survivor空間轉(zhuǎn)移的時候Survivor空間不夠了怎么辦狱窘?直接放到老年代去。

參考

Java垃圾回收(一)—— 回收機(jī)制

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末财搁,一起剝皮案震驚了整個濱河市蘸炸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌尖奔,老刑警劉巖搭儒,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異提茁,居然都是意外死亡淹禾,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門茴扁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來铃岔,“玉大人,你說我怎么就攤上這事峭火』傧埃” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵卖丸,是天一觀的道長纺且。 經(jīng)常有香客問我,道長稍浆,這世上最難降的妖魔是什么隆檀? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮粹湃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘泉坐。我一直安慰自己为鳄,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布腕让。 她就那樣靜靜地躺著孤钦,像睡著了一般歧斟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上偏形,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天静袖,我揣著相機(jī)與錄音,去河邊找鬼俊扭。 笑死队橙,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的萨惑。 我是一名探鬼主播捐康,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼庸蔼!你這毒婦竟也來了解总?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤姐仅,失蹤者是張志新(化名)和其女友劉穎花枫,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掏膏,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡劳翰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了壤追。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片磕道。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖行冰,靈堂內(nèi)的尸體忽然破棺而出溺蕉,到底是詐尸還是另有隱情,我是刑警寧澤悼做,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布疯特,位于F島的核電站,受9級特大地震影響肛走,放射性物質(zhì)發(fā)生泄漏漓雅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一朽色、第九天 我趴在偏房一處隱蔽的房頂上張望邻吞。 院中可真熱鬧,春花似錦葫男、人聲如沸抱冷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽旺遮。三九已至赵讯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間耿眉,已是汗流浹背边翼。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留鸣剪,地道東北人组底。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像西傀,于是被迫代替她去往敵國和親斤寇。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354

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