GolangGC之三色標記


Golang Garbage Collector

Go 1.3 mark and sweep方法

步驟:

  • 第一步暫停程序業務邏輯,找出所有對象,找出不可達對象,和可達對象
  • 第二步開始標記,程序找出它所有可達的對象,並做上標記
  • 標記完成,清除未標記的對象
  • 停止STW

業界常見的垃圾回收算法有以下幾種:

  • 引用計數:對每個對象維護一個引用計數,當引用該對象的對象被銷毀時,引用計數減1,當引用計數器為0時回收該對象。
    • 優點:對象可以很快地被回收,不會出現內存耗盡或達到某個閥值時才回收。
    • 缺點:不能很好地處理循環引用,而且實時維護引用計數,也有一定的代價。
    • 代表語言:Python、PHP、Swift
  • 標記-清除:從根變量開始遍歷所有引用的對象,引用的對象標記為”被引用”,沒有被標記的進行回收。
    • 優點:解決了引用計數的缺點。
    • 缺點:需要STW,即要暫時停掉程序運行。標記需要掃描整個heap。清除數據會產生heap碎片
    • 代表語言:Golang(其采用三色標記法)
  • 分代收集:按照對象生命周期長短划分不同的代空間,生命周期長的放入老年代,而短的放入新生代,不同代有不同的回收算法和回收頻率。
    • 優點:回收性能好
    • 缺點:算法復雜
    • 代表語言: JAVA

Go1.5 三色標記法

維護三個集合。

白色:所有對象起初全標記為白色,表明還沒有遍歷到的。

image-20210330205329094

GC開始需要做初始化灰色結點,即需要從定義的ROOT集合遍歷找到對應的白色結點,將對應的白色結點轉為灰色結點。

灰色:遍歷第一次得到灰色對象。

黑色:遍歷灰色結點,灰色結點如果仍能找到對象可達則標記為黑色,而下一個節點則標記為灰色。

重復第一步,直到灰色表中沒有任何對象。

收集白色對象(垃圾, 沒有再被任何使用到)

三色標記無STW的問題

三色標記STW性能比較低。

image-20210330211114082

存在的問題:灰色對象2引用的對象3,可能被用戶程序修改,而同時被標記位黑色的對象4又引用了該對象3,因為黑色對象已經不會被掃描,灰色對象2已經不再引用對象3,對象不能被標記為灰色,故最后被GC掉,但是對象4存在引用關系,就會發生錯誤。

image-20210330211650073

強弱三色不變式

強三色不變式 -- 破壞條件1

強制性的不允許黑色對象引用白色對象。

黑色可以引用灰色對象,但是不允許引用白色對象。

弱三色不變式 -- 破壞條件2

黑色可以引用白色對象,白色對象存在其他灰色對象對它的引用(存在另外一條路可達)。

image-20210330212034683

滿足強弱之一,即可保證對象不丟失

插入寫屏障 -- 對象被引用的時候 觸發的機制

A對象引用B對象,B對象被標記為灰色對象。(如果現在是黑色引用白色 就會強制把白色變為黑色 強三色不變式

image-20210330212726470

棧不啟用插入屏障,堆啟用插入屏障

在准備回收白色之前,需要重新掃描一遍棧空間,加入STW暫停保護棧,防止外界干擾

這樣相當於2遍掃描棧 如果沒有第一次 會發生什么?

刪除屏障 -- 對象被刪除的時候 觸發的機制

被刪除的對象,如果自身為灰色或者白色,那么被標記為灰色(弱三色不變式 保護灰色對象到白色對象的路徑不會斷)

image-20210330214154434

回收精度比較低,每次都可以活過一輪,在下一輪GC中被回收

Go 1.8 三色標記 + 混合寫

image-20210331175410792

具體操作:

  • GC開始將棧上的對象全部掃描並標記為黑色(不需要重復掃描以及STW)
  • GC期間,任何在棧上創建的對象,均為黑色
  • 被刪除的對象標記為灰色
  • 被添加的對象標記為灰色

滿足變形的弱三色不變式(結合插入、刪除寫屏障兩者的優點)

image-20210331180102322

1 滿足弱三色

2 滿足強三色

image-20210331180144130

混合寫屏障場景1:對象被一個堆對象刪除引用,成為棧對象的下游

image-20210331180746205

image-20210331181210460

image-20210331181146879

混合場景二:對象被一個棧對象刪除引用,成為另外一個棧對象的下游

image-20210401150601248

image-20210401150752332

混合場景三:對象被一個堆對象刪除引用,成為另外一個堆對象的下游

image-20210401150944096

對象10引用對象7的時候就會將對象7標記為灰色

image-20210401151141377

混合場景四:對象被一個堆對象刪除引用,成為另外一個棧對象的下游

image-20210401151318835

總結


免責聲明!

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



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