golang中的垃圾回收

golang中也使用分代概念分配内容,同样也是用标记清除算法做垃圾回收。

  • tiny :size < 16 bytes && has no pointer(noscan);

  • small :has pointer(scan) || (size >= 16 bytes && size <= 32 KB);

  • large :size > 32 KB

golang最新的垃圾回收中标记算法优化了挂起线程的算法,作为云原生语言,就是挂起几毫秒也是无法容忍的,最新的标记算法中引入了所谓的“三色标记法”来优化STW问题。

三色标记法

第一步:新创建的对象都是白色

第二步:从root Object开始遍历,经过的对象:A、C、D、B变为灰色

第三步:遍历灰色对象应用的对象,从白色变为灰色,同时将之前灰色的对象变成黑色

第四步:重复第三步,直到没有灰色对象

第五步:回收白色对象

 

屏障机制

在golang的GC回收时,没有挂起所有线程,所以在操作三色标记时,程序仍旧在操作对象,接下来演练一个场景

可以看出引出这个问题的核心原因

  • 黑色的对象指向了白色对象
  • 灰色对象也失去白色对象的关联

强-弱三色不变式

  • 强三色不变式:不存在黑色指向白色的关联
  • 弱三色不变式:所有被黑色对象引用的白色对象都处于灰色

插入屏障

      在A对象引用B对象时,B对象被标记为灰色。这个只操作堆内存中的数据,不操作栈内存中的数据,栈中的黑色指向白色时还是会STW,因为栈中的操作相对比较快

       案例:堆内存中的C对象引用了栈内存中的E,此时E标记为灰色

删除屏障

       被删除的对象,如果自身为灰色或者白色,那么被标记为灰色。

       案例:A扫描开始时删除了B的引用,B标记为灰色

混合写屏障

       在GO V1.8版本引入了混合写屏障机制

  • 在GC开始时,将栈中的对象都标记为黑色
  • GC期间创建栈对象永远标记为黑色
  • 被删除的对象标记为灰色
  • 被添加的对象标记为灰色       

这里需要大量的案例来说明这四个操作,就不一一叙述了,基本上就是上述的案例的微变。可以把条件赋值到上面的图中自行模拟。

posted @ 2023-02-20 17:05  ThirteenAnimation  阅读(49)  评论(0编辑  收藏  举报