三色標記法
白灰黑
初始時棠枉,所有對象都為白色设褐,
GC開始颠蕴,開啟SWT,遍歷堆棧root助析,將直接可達的對象標記為灰色犀被,
遍歷灰色結點,將直接可達的對象標記為灰色,自身標記為黑色外冀,
繼續(xù)執(zhí)行第三步同樣的步驟寡键,直到所有能夠訪問到的結點都被標記為黑色,
關閉SWT雪隧,回收所有白色標記的對象西轩。
如果沒有SWT员舵,程序正常執(zhí)行,可能會有如下的情況遭商,導致對象被誤當作垃圾回收固灵。
白色對象本來被一個灰色對象引用,但是該灰色對象將該引用賦給了黑色對象劫流,灰對白的引用斷開。此時丛忆,由于不會對黑色對象的引用進行檢測標記祠汇,即該白色節(jié)點即使被引用也無法被標記為灰色,最終當作垃圾處理掉熄诡。
三色標記法出現(xiàn)對象丟失可很,要滿足以下兩個條件:
條件一:白色對象被黑色對象引用
條件二:灰色對象與白色對象之間的可達關系遭到破壞
只要破壞兩個中的任何一個不會導致對象丟失的發(fā)生。
如何破壞兩個條件
強不變式:?不允許黑色對象引用白色對象
弱不變式:?黑色對象可以引用白色對象凰浮,但是白色對象必須直接或間接被灰色對象引用我抠。(保證白色對象一定會被掃描到)
當一個對象引用另外一個對象時,將另外一個對象標記為灰色袜茧。
插入屏障僅會在堆內存中生效菜拓,不對棧內存空間生效,這是因為go在并發(fā)運行時笛厦,大部分的操作都發(fā)生在棧上纳鼎,函數(shù)調用會非常頻繁。數(shù)十萬goroutine的棧都進行屏障保護自然會有性能問題裳凸。
如果一個棧對象 黑色引用白色對象贱鄙,白色對象依然會被當作垃圾回收。
因此姨谷,最后還需要對棧內存 進行STW逗宁,重新rescan,確保所有引用的被引用的棧對象都不會被回收梦湘。
刪除寫屏障
當一個白色對象被另外一個對象時解除引用時瞎颗,將該被引用對象標記為灰色(白色對象被保護)
缺點:產生內存冗余,如果上述該白色對象沒有被別的對象引用践叠,相當于還是垃圾言缤,但是這一輪垃圾回收并沒有處理掉他。
GC剛開始的時候禁灼,會將棧上的可達對象全部標記為黑色管挟。
GC期間,任何在棧上新創(chuàng)建的對象弄捕,均為黑色僻孝。
將棧上的可達對象全部標黑导帝,最后無需對棧進行STW,就可以保證棧上的對象不會丟失
堆上被刪除的對象標記為灰色
堆上新添加的對象標記為灰色
go 1.3 之前采用標記清除法穿铆,需要STW
go 1.5 采用三色標記法您单,插入寫屏障機制(只在堆內存中生效),最后仍需對棧內存進行STW
go 1.8 采用混合寫屏障機制荞雏,屏障限制只在堆內存中生效虐秦。避免了最后節(jié)點對棧進行STW的問題,提升了GC效率