Go V1.3 之前的標記清除(mark and sweep)
流程:
第⼀步,暫停程序業務邏輯, 找出不可達的對象,和可達對象。
第⼆步, 開始標記,程序找出它所有可達的對象,並做上標記。
第三步, 標記完了之后,然后開始清除未標記的對象.
第四步, 停⽌暫停,讓程序繼續跑。然后循環重復這個過程,直到process程序⽣命周期結束。
缺點:
STW,stop the world;讓程序暫停,程序出現卡頓 (重要問題)。
標記需要掃描整個heap
清除數據會產⽣heap碎⽚
將第四步和第三步換位置, 縮短STW的范圍
Go V1.5 三⾊標記法
流程:
第⼀步 , 就是只要是新創建的對象,默認的顏⾊都是標記為“⽩⾊”
第⼆步, 每次GC回收開始, 然后從根節點開始遍歷所有對象,把遍歷到的對象從⽩ ⾊集合放⼊“灰⾊”集合。
第三步, 遍歷灰⾊集合,將灰⾊對象引⽤的對象從⽩⾊集合放⼊灰⾊集合,之后將 此灰⾊對象放⼊⿊⾊集合
第四步, 重復第三步, 直到灰⾊中⽆任何對象.
第五步: 回收所有的⽩⾊標記表的對象. 也就是回收垃圾
如果三⾊標記法不被STW保護
條件1: ⼀個⽩⾊對象被⿊⾊對象引⽤ (⽩⾊被掛在⿊⾊下)
條件2: 灰⾊對象與它之間的可達關系的⽩⾊對象遭到破壞 (灰⾊同時丟了該⽩⾊)
兩個條件同時滿⾜,那么就會出現對象丟失的現象
強弱三⾊不變式
強三⾊不變式 破壞條件1 強制性的不允許黑色對象引用白色對象
弱三⾊不變式 破壞條件2 白色對象存在其他灰色對象對其的引用 或者可達它的鏈路上游存在灰色對象
如果三⾊標記滿⾜強弱不變式之⼀,即可保證不丟失對象
屏障機制
插⼊屏障
對象被引⽤時 觸發的機制
具體操作: 在A對象引⽤B對象的時候,B對象被標記 為灰⾊。(將B掛在A下游,B必須被標記為灰⾊) 滿⾜: 強三⾊不變式. (不存在⿊⾊對象引⽤⽩⾊對象的 情況了, 因為⽩⾊會強制變成灰⾊)
不⾜ 結束時需要STW來重新掃描棧,⼤約需要10~100ms
刪除屏障
對象被刪除時 觸發的機制
具體操作: 被刪除的對象,如果⾃身為灰⾊或者⽩⾊,那 么被標記為灰⾊。 滿⾜: 弱三⾊不變式. (保護灰⾊對象到⽩⾊對象的路徑不 會斷)
不足 回收精度低, ⼀個對象即使被刪除了最后⼀個指向它的指針也依舊可以活過這⼀輪, 在下⼀輪GC中被清理掉。
Go V1.8 混合寫屏障機制
具體操作
1、GC開始將棧上的對象全部掃描並標記為⿊⾊(之后不再進⾏第⼆次重復掃描,⽆需STW)
2、GC期間,任何在棧上創建的新對象,均為⿊⾊。
3、被刪除的對象標記為灰⾊。
4、被添加的對象標記為灰⾊。
滿⾜: 變形的弱三⾊不變式. (結合了插⼊、刪除寫屏障兩者的有點)