深入理解GO的GC

Gov1.3之前的标记清除法(mark and sweep)

  1. 进行STW暂停

  2. 把所有的程序可达对象标记

  3. 清除所有进行没有被标记的对象

  4. 去除暂停,进行程序,并且重复过程

缺点:

  1. 出现了SWT(stop the world)过程,程序会有卡顿(重要问题
  2. 标记需要扫描整个heap
  3. 清除数据会产生heap碎片

Gov1.5的三色标记法

  1. 程序创建,把所有的对象标记为白色
  2. 遍历Root Set(不是递归的,直走一步)得到灰色节点
  3. 遍历灰色节点,白色标记为灰色,并且刚才的灰色变成黑色
  4. 重复以上步骤,直到灰色没有对象
  5. 收集所有的垃圾(标记为白色)

三色标记没有SWT会出现的问题:

出现对象丢失(下面是出现的条件):

  1. 一个白色对象被黑色对象引用
  2. 灰色对象与它之间的可达关系的白色对象被破坏(此时灰色对象与白色对象变成不可达)

强弱三色不变式

破坏对象丢失的俩个同时成立

强三色不变式

强制性不允许黑色对象引用白色对象(破坏条件1)

弱三色不变式

黑色对象可以引用白色对象,白色对象存在其他灰色对象对它的引用,或者可达它的链路上游存在灰色对象(破坏条件2)

Gov1.8屏障机制

插入屏障

不在栈上使用,因为考虑到速度

触发时机:对象被引用时

具体操作:在 A引用B,B标记为灰色(本质是 原本黑色引用白色,会变成黑色引用灰色

满足:强三色不变式

插入写屏障:

需要SWT实

先在堆上,进行三色法

然后把所有的栈上置白,进行三色法

删除屏障

只在堆上,不在栈上

触发时机:对象被删除时

具体操作:被删除对象,如果自身为灰色或者白色,那么被标记为灰色

满足:弱三色不变式(灰色灰色对象到白色对决不会断)

不足:下一轮会被删除

混合写屏障

具体操作:

  1. GC开始将栈上的对象全部扫描并且标记为黑色(之后不会二次重复扫描,无需SWT)
  2. GC期间,任何在栈上创建的新对象,均为黑色
  3. 被删除的对象标记为灰色
  4. 被添加的对象标记为灰色

满足:变形的弱三色不等式

场景1:对象被一个堆对象删除引用,成为栈对象的下游

  1. 对象7添加到对象1下游,因为栈不启动学屏障,所以直接挂在下面

  1. 对象4删除对象7的引用,因为对象4是堆区,所以触发写屏障(删除即赋新值为null),标记背删除对象7为灰

场景2:对象被一个栈对象删除引用,成为另一个栈对象的下游

  1. 新建一个对象9在栈上(混合写屏障模式中,GC过程中任何新创建的对象均标记为黑色)

  1. 对象9添加下游引用栈对象3(直接添加,栈不启动屏障,无屏障效果)

  2. 对象2删除对象3的引用关系(直接删除,栈不启动写屏障,无屏障效果)

场景3:对象被一个堆对象引用,成为堆对象的下游

场景4:一个栈对象删除引用,成为另一个堆对象的下游