golang垃圾回收
1 使用写屏障的原因:对于和用户程序并发运行的垃圾回收算法,用户程序会一直修改内存,所以需要记录下来。就问为了记录引用的修改,写屏障通俗的说就是垃圾回收的同时,由于程序还在运行,所以变量间的引用也会发生变化,这时如果仍然只执行三色标记就会发生错误,所以需要插入写屏障,对那些修改变量间引用的程序进行标记,
写屏障分为插入写屏障和删除写屏障,
插入写屏障:A为黑色B为白色,如果A引用了B,就将B标记为灰色,
删除写屏障:B为灰色,C为白色,B指向C的引用删除了,则C标记为灰色,
Stack scan:Collect pointers from globals and goroutine stacks。收集根对象(全局变量,和G stack),开启写屏障。全局变量、开启写屏障需要STW,G stack只需要停止该G就好,时间比较少。
Mark: Mark objects and follow pointers。标记所有根对象, 和根对象可以到达的所有对象不被回收。
Mark Termination: Rescan globals/changed stack, finish mark。重新扫描全局变量,和上一轮改变的stack(写屏障),完成标记工作。这个过程需要STW。(即对比和写屏障中记录的区别,)
Sweep: 按标记结果清扫span
- 第一次STW会准备根对象的扫描, 启动写屏障(Write Barrier)和辅助GC(mutator assist).
- 第二次STW会重新扫描部分根对象, 禁用写屏障(Write Barrier)和辅助GC(mutator assist).
https://www.bookstack.cn/read/For-learning-Go-Tutorial/spilt.7.src-spec-02.0.md
https://www.jianshu.com/p/8b0c0f7772da
https://github.com/KeKe-Li/For-learning-Go-Tutorial/blob/master/src/spec/02.0.md
https://www.bookstack.cn/read/For-learning-Go-Tutorial/spilt.7.src-spec-02.0.md