GC算法-增量式垃圾回收


概述

增量式垃圾回收也並不是一個新的回收算法, 而是結合之前算法的一種新的思路.

之前說的各種垃圾回收, 都需要暫停程序, 執行GC, 這就導致在GC執行期間, 程序得不到執行. 因此出現了增量式垃圾回收, 它並不會等GC執行完, 才將控制權交回程序, 而是一步一步執行, 跑一點, 再跑一點, 逐步完成垃圾回收, 在程序運行中穿插進行. 極大地降低了GC的最大暫停時間.

實現

增量式垃圾回收只是提出了這樣的一個概念, 並沒有限定如何去實現. 想必也有不同的實現思路吧.

三色標記算法

此算法將對象做不同的標記

  • 白色: 未搜索過的對象
  • 灰色: 正在搜索的對象
  • 黑色: 搜索完的對象

這里的顏色只是一種虛構的概念, 就是在對象上打tag.

在GC開始執行時, 所有對象都是白色的, 然后將根集合的對象放到棧中, 並標記為灰色, 依次處理. 將對象從棧中取出, 遞歸搜索所有子對象, 並標記為灰色, 當子對象搜索完后, 就將對象標記為黑色. 這樣, 當一個對象搜索完后, 該對象及其關聯的所有子對象就都是黑色的了. 當標記階段結束后, 所有活動對象都是黑色, 垃圾對象則是白色.

此算法就是通過這樣, 逐步對對象進行標記.

三色標記應用於標記清除中

標記清除算法在標記階段, 應用三色標記逐步標記, 每次搜索一定次數后, 就返回執行, 等待下次繼續標記, 將標記分為小段穿插在程序中運行.

在清除階段, 也可以設置一個次數, 每遍歷一定數量的對象, 就返回等待下次繼續.

三色標記不光可以應用於標記清除中, 也可以應用於其他標記算法中.

問題

你以為這就完了么? 天真, 想象一下這樣的場景:

// 假設 c, d 是兩個對象
$b->son = $d;
$b->son = $c;
// 在這個時候, 開始GC, 將d標記為白色, 將c標記為黑色. 返回
$b->son = $d;
// GC清除階段, 將c對象保留, 將d對象回收

這樣就出現問題了, 也就是說如果我已經對其進行過標記了, 但它在我標記之后進行了修改, 就會導致清除階段的對象很可能不是當時的真實情況.

那么如何防止這種遺漏的標記呢? 簡單粗暴一點, 每次更新指針的時候, 如果對象是白色的, 就將其塗成灰色, 放到待搜索的棧中, 之后重新對其進行標記. 這樣就可以保證不會回收到引用的對象, 雖然可能會有一些遺漏對象沒有回收, 但是 who care? 下一次再回收咯.

也有不同的寫入屏障處理方法, 在更新對象時進行不同操作.

大概如此....


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM