JVM 讀書(shū)筆記(二)之垃圾收集器 & 垃圾收集算法

一巫财、垃圾收集器判斷對(duì)象已死的算法

1.對(duì)象已死嗎?

判斷方法有以下兩種:

  • 1.引用計(jì)數(shù)法

    給對(duì)象添加一個(gè)引用計(jì)數(shù)器缺亮,每當(dāng)有一個(gè)地方引用它時(shí)翁涤,計(jì)數(shù)器就加1;當(dāng)引用失效時(shí)萌踱,計(jì)數(shù)器數(shù)值就減1葵礼;任何時(shí)刻計(jì)數(shù)器為0的對(duì)象就是不可能再被使用的。
    但是這種方法有個(gè)弊端:很難解決對(duì)象之間相互循環(huán)引用的問(wèn)題并鸵。

  • 2.可達(dá)性分析算法

    當(dāng)一個(gè)對(duì)象到 GC Roots 沒(méi)有任何引用鏈相連(用圖論的話來(lái)說(shuō)就是從 GC Roots 到這個(gè)對(duì)象不可達(dá)時(shí))鸳粉,證明這個(gè)對(duì)象是不可用的。

  • 3.四種引用類型

    • 強(qiáng)引用:Object obj = new Object()园担,這就是強(qiáng)引用届谈。只要強(qiáng)引用還存在,垃圾收集器永遠(yuǎn)不會(huì)回收掉被引用的對(duì)象弯汰。

    • 軟引用:軟引用用來(lái)描述一些還有用但并非必需的對(duì)象艰山。對(duì)于軟引用關(guān)聯(lián)的對(duì)象,在系統(tǒng)將要發(fā)生內(nèi)存溢出異常之前咏闪,將會(huì)把這些對(duì)象列進(jìn)回收范圍之中進(jìn)行第二次回收曙搬。如果這次回收還沒(méi)有足夠的內(nèi)存,才會(huì)拋出內(nèi)存溢出異常鸽嫂。使用 SoftRefrence類實(shí)現(xiàn)軟引用纵装。

    • 弱引用:弱引用也是用來(lái)描述非必須對(duì)象的,但是強(qiáng)度比軟引用更弱据某。被弱引用關(guān)聯(lián)的對(duì)象只能生存到下一次垃圾回收之前橡娄。垃圾收集器工作時(shí),無(wú)論當(dāng)前內(nèi)存是否足夠癣籽,都會(huì)回收掉只被弱引用關(guān)聯(lián)的對(duì)象挽唉。使用 WeakRefrence類實(shí)現(xiàn)弱引用。

    • 虛引用:這是最弱的一種引用關(guān)系筷狼。對(duì)象的生存時(shí)間與虛引用完全沒(méi)有關(guān)系橱夭,無(wú)法通過(guò)虛引用獲得對(duì)象實(shí)例。虛引用的唯一作用就是在對(duì)象被垃圾回收時(shí)收到一個(gè)系統(tǒng)通知桑逝。使用 PhantomRefrence類實(shí)現(xiàn)虛引用。


二俏让、垃圾收集算法

  • 1.標(biāo)記-清除算法(Mark-Sweep

    最基礎(chǔ)的收集算法是“標(biāo)記-清除算法”楞遏。這個(gè)算法分為兩個(gè)階段:標(biāo)記清除茬暇。
    標(biāo)記:在標(biāo)記階段,collectormutator根對(duì)象開(kāi)始進(jìn)行遍歷寡喝,對(duì)從 mutator根對(duì)象可以訪問(wèn)到的對(duì)象都打上一個(gè)標(biāo)識(shí)糙俗,一般是在對(duì)象的header 中,將其記錄為可達(dá)對(duì)象预鬓。

清除:在清除階段巧骚,collector 對(duì)堆內(nèi)存(heap memory)從頭到尾進(jìn)行線性的遍歷,通過(guò)讀取對(duì)象的 header 信息,如果發(fā)現(xiàn)某個(gè)對(duì)象沒(méi)有標(biāo)記為可達(dá)對(duì)象,則就將其回收格二。標(biāo)記為可達(dá)對(duì)象的對(duì)象劈彪,將重新去掉 header信息的標(biāo)志位,以準(zhǔn)備下次垃圾回收顶猜。

但是這種方法有2個(gè)不足:
1.效率問(wèn)題沧奴,標(biāo)記和清除兩個(gè)過(guò)程效率都不高。
2.空間問(wèn)題长窄,標(biāo)記清除之后會(huì)產(chǎn)生大量的不連續(xù)的內(nèi)存碎片滔吠,空 間碎片太多可能會(huì)導(dǎo)致以后在程序運(yùn)行過(guò)程中需要分配較大對(duì)象時(shí),無(wú)法找到足夠的連續(xù)內(nèi)存而不得不提前觸發(fā)另一次垃圾回收動(dòng)作挠日。

標(biāo)記-清除算法
  • 2.復(fù)制算法 (Copying)

    復(fù)制算法將內(nèi)存劃分為兩個(gè)區(qū)間疮绷,在任意時(shí)間點(diǎn),所有動(dòng)態(tài)分配的對(duì)象都只能分配在其中一個(gè)區(qū)間(稱為活動(dòng)區(qū)間)嚣潜,而另外一個(gè)區(qū)間(稱為空閑區(qū)間)則是空閑的冬骚。

    當(dāng)有效內(nèi)存空間耗盡時(shí),JVM 將暫停程序運(yùn)行郑原,開(kāi)啟復(fù)制算法 GC 線程唉韭。接下來(lái) GC 線程會(huì)將活動(dòng)區(qū)間內(nèi)的存活對(duì)象,全部復(fù)制到空閑區(qū)間犯犁,且嚴(yán)格按照內(nèi)存地址依次排列属愤,與此同時(shí),GC線程將更新存活對(duì)象的內(nèi)存引用地址指向新的內(nèi)存地址酸役。

    而此時(shí)住诸,其實(shí)空閑區(qū)間和活動(dòng)區(qū)間已經(jīng)進(jìn)行了交換,垃圾對(duì)象已經(jīng)全部留在了原來(lái)的活動(dòng)區(qū)間涣澡,也就是現(xiàn)在的空閑區(qū)間贱呐。事實(shí)上,在活動(dòng)區(qū)間轉(zhuǎn)換為空間區(qū)間的同時(shí)入桂,垃圾對(duì)象已經(jīng)被一次性全部回收奄薇。

    優(yōu)點(diǎn):每次內(nèi)存回收都是對(duì)整個(gè)半?yún)^(qū)進(jìn)行內(nèi)存回收,內(nèi)存分配時(shí)不用考慮內(nèi)存碎片的問(wèn)題抗愁,只要移動(dòng)堆頂指針馁蒂,按照順序分配內(nèi)存即可呵晚,實(shí)現(xiàn)簡(jiǎn)單,運(yùn)行高效沫屡。

    缺點(diǎn):1.代價(jià)是將內(nèi)存縮小為原來(lái)的一半饵隙;2.如果對(duì)象的存活率很高,我們可以極端一點(diǎn)沮脖,假設(shè)是100%存活金矛,那么我們需要將所有對(duì)象都復(fù)制一遍,并將所有引用地址重置一遍勺届。復(fù)制這一工作所花費(fèi)的時(shí)間驶俊,在對(duì)象存活率達(dá)到一定程度時(shí),將會(huì)變的不可忽視涮因。

    復(fù)制算法比較適合的場(chǎng)景:對(duì)象的存活率要非常低才行废睦,而且最重要的是,我們必須要克服50%內(nèi)存的浪費(fèi)养泡。

    下面看看復(fù)制算法回收前和回收后的內(nèi)存模型:

    回收前:

    回收前

    回收后:

    回收后

    由于 1嗜湃,4 對(duì)象不可達(dá),被回收掉澜掩,剩下的對(duì)象按照順序分配內(nèi)存购披。這時(shí)右邊的區(qū)域變成了活動(dòng)區(qū)間,左邊變成空閑區(qū)間肩榕,下次垃圾回收將再次調(diào)換回來(lái)刚陡。

  • 3.標(biāo)記-整理算法 (Mark-Compact)

    標(biāo)記-整理算法與標(biāo)記-清除算法非常相似,它也是分為兩個(gè)階段:標(biāo)記和整理株汉。

    標(biāo)記:它的第一個(gè)階段與標(biāo)記-清除算法是一模一樣的筐乳,均是遍歷 GC Roots,然后將存活的對(duì)象標(biāo)記乔妈。

    整理:移動(dòng)所有存活的對(duì)象蝙云,且按照內(nèi)存地址次序依次排列,然后將末端內(nèi)存地址以后的內(nèi)存全部回收路召。因此勃刨,第二階段才稱為整理階段。

    標(biāo)記-整理算法 GC 前后的圖示與復(fù)制算法的圖非常相似股淡,只是沒(méi)有了活動(dòng)區(qū)間和空閑區(qū)間的區(qū)別身隐,而過(guò)程又與標(biāo)記-清除算法非常相似。

    回收前

    回收前

    標(biāo)記

    回收前

    標(biāo)記為 1 表示對(duì)象仍然可達(dá)唯灵。

    整理

    回收前

    可見(jiàn)贾铝,1,4 對(duì)象被回收了,剩下的存活對(duì)象的內(nèi)存按照順序排列垢揩,這點(diǎn)很像復(fù)制算法大脉,回收后不存在內(nèi)存碎片問(wèn)題,而且避免了內(nèi)存減半的高額代價(jià)水孩。但是處理過(guò)程又想標(biāo)記-清除算法英古,不僅要標(biāo)記所有存活對(duì)象茅主,還要整理所有存活對(duì)象的引用地址用踩。效率也不高怀愧,在效率上要低于復(fù)制算法骚勘。

參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末旨别,一起剝皮案震驚了整個(gè)濱河市患朱,隨后出現(xiàn)的幾起案子译蒂,更是在濱河造成了極大的恐慌牢酵,老刑警劉巖悬包,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異馍乙,居然都是意外死亡布近,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門丝格,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)撑瞧,“玉大人,你說(shuō)我怎么就攤上這事显蝌≡に牛” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵曼尊,是天一觀的道長(zhǎng)酬诀。 經(jīng)常有香客問(wèn)我,道長(zhǎng)骆撇,這世上最難降的妖魔是什么瞒御? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮艾船,結(jié)果婚禮上葵腹,老公的妹妹穿的比我還像新娘。我一直安慰自己屿岂,他們只是感情好践宴,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著爷怀,像睡著了一般阻肩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天烤惊,我揣著相機(jī)與錄音乔煞,去河邊找鬼。 笑死柒室,一個(gè)胖子當(dāng)著我的面吹牛渡贾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播雄右,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼空骚,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了擂仍?” 一聲冷哼從身側(cè)響起囤屹,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎逢渔,沒(méi)想到半個(gè)月后肋坚,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肃廓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年智厌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片亿昏。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡峦剔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出角钩,到底是詐尸還是另有隱情吝沫,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布递礼,位于F島的核電站惨险,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏脊髓。R本人自食惡果不足惜辫愉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望将硝。 院中可真熱鬧恭朗,春花似錦、人聲如沸依疼。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)律罢。三九已至膀值,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背沧踏。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工歌逢, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人翘狱。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓秘案,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親潦匈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子踏烙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348