https://www.cnblogs.com/cxy2020/p/16321884.html
https://developer.aliyun.com/article/861507
插入/刪除寫屏障都存在漏(少)回收,但是不會(huì)誤(多)回收
插入寫屏障可以認(rèn)為是一個(gè)保守設(shè)計(jì),所有新分配的堆對(duì)象如果被黑/灰對(duì)象指向都標(biāo)記為灰色,在下一輪GC再回收。缺點(diǎn)是標(biāo)記完回棧上掃一遍需要stw。
刪除寫屏障也可以認(rèn)為是一個(gè)保守設(shè)計(jì),需要所有可達(dá)根對(duì)象被標(biāo)記了(期間stw)才能開啟刪除寫屏障。缺點(diǎn)是
為了避免內(nèi)存空間錯(cuò)誤釋放,需要stw,為了不stw,推出三色不變性,負(fù)責(zé)該原則就不需要stw。
強(qiáng)三色不變式(對(duì)應(yīng)插入寫屏障)
不允許黑色對(duì)象引用白色對(duì)象

- 插入寫屏障
具體操作:A,新增對(duì)象B且添加A->B,插入的新對(duì)象B標(biāo)記為灰色。
writePointer(slot, ptr):
shade(ptr)
*slot = ptr
插入屏障僅會(huì)在堆內(nèi)存(父節(jié)點(diǎn)是堆對(duì)象)中生效,不對(duì)棧內(nèi)存空間生效(在棧上指向新對(duì)象時(shí)不會(huì)置黑),這是因?yàn)間o在并發(fā)運(yùn)行時(shí),數(shù)十萬goroutine的棧都進(jìn)行屏障保護(hù)自然會(huì)有性能問題。


弊端:由于棧上的對(duì)象沒有插入寫機(jī)制,在掃描完成后,仍然可能存在棧上的白色對(duì)象指向黑色的堆對(duì)象,所以在最后需要對(duì)棧上的空間進(jìn)行STW,防止對(duì)象誤刪除。
弱三色不變式
黑色對(duì)象可以引用白色對(duì)象,但是白色對(duì)象的上游必須存在灰色對(duì)象

- 刪除寫屏障
具體操作:A->B,刪除->,則被刪除的對(duì)象B標(biāo)記為灰色。
writePointer(slot, ptr):
shade(*slot)
*slot = ptr
刪除寫屏障(基于起始快照的寫屏障)有一個(gè)前提條件,就是起始的時(shí)候,把整個(gè)根部掃描一遍,讓所有的可達(dá)對(duì)象全都在灰色保護(hù)下(根黑,下一級(jí)在堆上的全灰),之后利用刪除寫屏障捕捉內(nèi)存寫操作,確保弱三色不變式不被破壞,就可以保證垃圾回收的正確性(但是需要stw)。


一個(gè)對(duì)象的引用被刪除后,即使沒有其他存活的對(duì)象引用它,它仍然會(huì)活到下一輪。如此一來,會(huì)產(chǎn)生很多的冗余掃描成本,且降低了回收精度。

混合寫屏障
插入寫屏障:結(jié)束時(shí)需要STW來重新掃描棧,標(biāo)記棧上引用的白色對(duì)象的存活;
刪除寫屏障:回收精度低,GC開始時(shí)STW掃描堆棧來記錄初始快照,這個(gè)過程會(huì)保護(hù)開始時(shí)刻的所有存活對(duì)象。
GC期間,任何在棧上新創(chuàng)建的對(duì)象,均為黑色。GC剛開始的時(shí)候,會(huì)將棧上的可達(dá)對(duì)象全部標(biāo)記為黑色(解除刪除寫屏障的stw)。屏障限制只在堆內(nèi)存中生效,且棧上全部標(biāo)記黑色無需stw,提升了GC效率。
1、GC開始將棧上的可達(dá)對(duì)象全部掃描并標(biāo)記為黑色 (之后不再進(jìn)行第二次重復(fù)掃描,無需STW)
2、GC期間,任何在棧上創(chuàng)建的新對(duì)象,均為黑色。(惰性回收)(解除了刪除寫屏障的stw)
3、插入寫屏障+刪除寫屏障(堆上元素指向其他對(duì)象的時(shí)候開啟)
- 全程沒有stw