GC算法-增量式垃圾回收
概述
增量式垃圾回收也并不是一個新的回收算法, 而是結(jié)合之前算法的一種新的思路.
之前說的各種垃圾回收, 都需要暫停程序, 執(zhí)行GC, 這就導(dǎo)致在GC執(zhí)行期間, 程序得不到執(zhí)行. 因此出現(xiàn)了增量式垃圾回收, 它并不會等GC執(zhí)行完, 才將控制權(quán)交回程序, 而是一步一步執(zhí)行, 跑一點(diǎn), 再跑一點(diǎn), 逐步完成垃圾回收, 在程序運(yùn)行中穿插進(jìn)行. 極大地降低了GC的最大暫停時間.
實(shí)現(xiàn)
增量式垃圾回收只是提出了這樣的一個概念, 并沒有限定如何去實(shí)現(xiàn). 想必也有不同的實(shí)現(xiàn)思路吧.
三色標(biāo)記算法
此算法將對象做不同的標(biāo)記
- 白色: 未搜索過的對象
- 灰色: 正在搜索的對象
- 黑色: 搜索完的對象
這里的顏色只是一種虛構(gòu)的概念, 就是在對象上打tag.
在GC開始執(zhí)行時, 所有對象都是白色的, 然后將根集合的對象放到棧中, 并標(biāo)記為灰色, 依次處理. 將對象從棧中取出, 遞歸搜索所有子對象, 并標(biāo)記為灰色, 當(dāng)子對象搜索完后, 就將對象標(biāo)記為黑色. 這樣, 當(dāng)一個對象搜索完后, 該對象及其關(guān)聯(lián)的所有子對象就都是黑色的了. 當(dāng)標(biāo)記階段結(jié)束后, 所有活動對象都是黑色, 垃圾對象則是白色.
此算法就是通過這樣, 逐步對對象進(jìn)行標(biāo)記.
三色標(biāo)記應(yīng)用于標(biāo)記清除中
標(biāo)記清除算法在標(biāo)記階段, 應(yīng)用三色標(biāo)記逐步標(biāo)記, 每次搜索一定次數(shù)后, 就返回執(zhí)行, 等待下次繼續(xù)標(biāo)記, 將標(biāo)記分為小段穿插在程序中運(yùn)行.
在清除階段, 也可以設(shè)置一個次數(shù), 每遍歷一定數(shù)量的對象, 就返回等待下次繼續(xù).
三色標(biāo)記不光可以應(yīng)用于標(biāo)記清除中, 也可以應(yīng)用于其他標(biāo)記算法中.
問題
你以為這就完了么? 天真, 想象一下這樣的場景:
// 假設(shè) c, d 是兩個對象 $b->son = $d; $b->son = $c; // 在這個時候, 開始GC, 將d標(biāo)記為白色, 將c標(biāo)記為黑色. 返回 $b->son = $d; // GC清除階段, 將c對象保留, 將d對象回收這樣就出現(xiàn)問題了, 也就是說如果我已經(jīng)對其進(jìn)行過標(biāo)記了, 但它在我標(biāo)記之后進(jìn)行了修改, 就會導(dǎo)致清除階段的對象很可能不是當(dāng)時的真實(shí)情況.
那么如何防止這種遺漏的標(biāo)記呢? 簡單粗暴一點(diǎn), 每次更新指針的時候, 如果對象是白色的, 就將其涂成灰色, 放到待搜索的棧中, 之后重新對其進(jìn)行標(biāo)記. 這樣就可以保證不會回收到引用的對象, 雖然可能會有一些遺漏對象沒有回收, 但是 who care? 下一次再回收咯.
也有不同的寫入屏障處理方法, 在更新對象時進(jìn)行不同操作.
大概如此…
總結(jié)
以上是生活随笔為你收集整理的GC算法-增量式垃圾回收的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu14升级MySQL
- 下一篇: 1971旗舰cpu intel_CPU的