golang 的 GC 一直是大家诟病最多的话题之一。下面是 golang 不同版本之中有一些重要改进:
- v1.1 STW
- v1.3 Mark STW,Sweep 并行
- v1.5 三色标记法
- v1.8 hybrid write barrier
三色标记法
三色标记法,就是将对象按状态分为三类,并分为赋予三种颜色:
1、白色对象(可能死亡):未被回收器访问到的对象。所有对象在起始阶段均为白色,在回收结束后白色对象被回收。
2、灰色对象(中间态):已被回收器访问到的对象。但可能存在指向其他对象的引用。
3、黑色对象(确定存活):已被回收器访问到的对象,且不存在指向其他对象的引用。
除此之外,在 v1.8 版本重还引入写屏障的概念:在 GC 执行期间,新创建的对象会被默认赋予灰色对象,以便垃圾回收的正常执行。
标记起始阶段
1、STW
2、确定 GC ROOT,并将其置为灰色
3、引入写屏障
标记阶段
1、标记与业务并行
标记终止阶段
1、STW
2、移除写屏障
清除阶段
1、回收白色对象
三色标记法,大大减少了 GC 的 STW 时间,使得标记阶段与业务并行。
引入写屏障,使得程序在 GC 期间会有额外的性能消耗。
逃逸分析
用来在编译阶段确认对象的内存是分配到堆中还是分配到栈中。
调优:避免在GC期间引入耗时操作
背景:希望收集线上 GC 日志,以便用于后续分析。
实现:开启 GODEBUG=gctrace=1,并将输出流指向某文件。
导致:监控显示,线上业务必定间隔性抖动。
原因:GC 日志输出属于 STW 期间,原本 STW 基于内存完成,但现在强行引入磁盘 IO,导致堆程序造成性能影响。
👇👇👇
本文作者: Czasg
版权声明: 转载请注明出处哦~👮