插入/刪除寫屏障

https://www.cnblogs.com/cxy2020/p/16321884.html
https://developer.aliyun.com/article/861507

  • 插入/刪除寫屏障都存在漏(少)回收,但是不會誤(多)回收

  • 插入寫屏障可以認為是一個保守設計,所有新分配的堆對象如果被黑/灰對象指向都標記為灰色,在下一輪GC再回收。缺點是標記完回棧上掃一遍需要stw。

  • 刪除寫屏障也可以認為是一個保守設計,需要所有可達根對象被標記了(期間stw)才能開啟刪除寫屏障。缺點是


為了避免內(nèi)存空間錯誤釋放,需要stw,為了不stw,推出三色不變性,負責該原則就不需要stw。

強三色不變式(對應插入寫屏障)

不允許黑色對象引用白色對象

image.png
  • 插入寫屏障

具體操作:A,新增對象B且添加A->B,插入的新對象B標記為灰色。

writePointer(slot, ptr):
shade(ptr)
*slot = ptr

插入屏障僅會在堆內(nèi)存(父節(jié)點是堆對象)中生效,不對棧內(nèi)存空間生效(在棧上指向新對象時不會置黑),這是因為go在并發(fā)運行時,數(shù)十萬goroutine的棧都進行屏障保護自然會有性能問題。

image.png
image.png

弊端:由于棧上的對象沒有插入寫機制,在掃描完成后,仍然可能存在棧上的白色對象指向黑色的堆對象,所以在最后需要對棧上的空間進行STW,防止對象誤刪除。

弱三色不變式

黑色對象可以引用白色對象,但是白色對象的上游必須存在灰色對象

image.png
  • 刪除寫屏障

具體操作:A->B,刪除->,則被刪除的對象B標記為灰色。

writePointer(slot, ptr):
shade(*slot)
*slot = ptr

刪除寫屏障(基于起始快照的寫屏障)有一個前提條件,就是起始的時候,把整個根部掃描一遍,讓所有的可達對象全都在灰色保護下(根黑,下一級在堆上的全灰),之后利用刪除寫屏障捕捉內(nèi)存寫操作,確保弱三色不變式不被破壞,就可以保證垃圾回收的正確性(但是需要stw)。

image.png
image.png

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

image.png

混合寫屏障

  • 插入寫屏障:結(jié)束時需要STW來重新掃描棧,標記棧上引用的白色對象的存活;

  • 刪除寫屏障:回收精度低,GC開始時STW掃描堆棧來記錄初始快照,這個過程會保護開始時刻的所有存活對象。

GC期間,任何在棧上新創(chuàng)建的對象,均為黑色。GC剛開始的時候,會將棧上的可達對象全部標記為黑色(解除刪除寫屏障的stw)。屏障限制只在堆內(nèi)存中生效,且棧上全部標記黑色無需stw,提升了GC效率。

1、GC開始將棧上的可達對象全部掃描并標記為黑色 (之后不再進行第二次重復掃描,無需STW)

2、GC期間,任何在棧上創(chuàng)建的新對象,均為黑色。(惰性回收)(解除了刪除寫屏障的stw)

3、插入寫屏障+刪除寫屏障(堆上元素指向其他對象的時候開啟)

  • 全程沒有stw
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容