Golang深入学习之GC回收机制

0、各个版本机制

相关概念

  • 垃圾回收
  • 内存管理
  • 自动释放
  • 三色标记法
  • STW(stop the world)

GO v1.3及之前GC - 标记清除法

  • STW强制暂停当前程序的所有逻辑业务
  • 标记清除(mark and sweep):执行STW,遍历对所有的可达对象做上标记,(可达对象:通过该程序创建、调用和依赖的对象,不包括依赖该程序中对象的对象),剩余不可达的对象(即未标记的对象)清除
  • 缺点:会使用STW,让程序暂停,性能低,程序卡顿;标记需要扫描整个heap,复杂度高;会产生heap碎片,随后的碎片清理问题。

GO v1.5改进GC - 三色标记法

  • 三个标记表:White白色标记表、Gray灰色标记表、Black黑色标记表,初始所有对象都记录在White.
  • 遍历第一层:对程序的Root Set根节点集合进行遍历,只遍历一层,将遍历到的对象从White中取出,存入Gray.
  • 遍历Gray标记表:将Gray中的所有对象遍历一层,遍历后将结果对象加入Gray,并将原本Gray中的对象加入Black.
  • 循环往复遍历Gray,直至Gray 中无对象,此时White中的所有对象都可作为Garbage。.

STW的必要性(在三色标记法中)

  • 存在的隐患:在整个GC过程中,若不使用STW时同时满足两个条件,可能会造成对象丢失
  • 条件1:Black中的对象引用了一个White中的对象,比如对象C.
  • 条件2:GC过程中,Gray中的对象舍弃了对于White中特定对象的引用,比如对象C.

1、Golang采用的优化方法

强三色不变式

  • 破坏条件1:强制性的不允许Black中对象引用White中对象。

弱三色不变式

  • 破坏条件2:Black对象可以引用White对象,但此White对象必须存在其他Gray对其引用,或者可达此White对象的链路上上游存在Gray对象。

2、实现方法 - 屏障机制

插入屏障

  • 机制:在Black对象A引用新的对象B时,对象B立马被标记为Gray,即将对象B挂在对象A的下游。(满足强三色不变式)
  • 不足:插入屏障不可以用于栈空间,只对位于堆空间的对象执行插入屏障机制,所以每次结束时,需要使用STW机制重新扫描栈空间的对象,大约需要10~100ms.(满足弱三色不变式)

删除屏障

  • 机制:被删除的对象,如果自身为Gray or White,那么被标记为Gray.
  • 不足回收精度较低,通过删除屏障存活下的对象可以多活一轮,当然,到了下一轮GC如果其没什么变化,依旧会被删除。

3、混合写屏障

机制

  • GC开始,对栈上所有对象扫描并标记为黑色(之后不再进行第二次重复扫描,无需STW)。
  • GC期间,任何在栈上创建的新对象,均标记为黑色
  • GC期间,被删除的对象标记为灰色;被添加的对象标记为灰色(在栈空间上不启用)。

场景一

  • 场景内容:对象A被一个堆对象B删除引用,成为栈对象C的下游。
  • 场景结果:对象A标记为Gray.

场景二

  • 场景内容:对象A被一个栈对象B删除引用,成为另一个栈对象C的下游。
  • 场景结果:对象A标记为Black.

场景三

  • 场景内容:对象A被一个堆对象B删除引用,成为另一个堆对象C的下游。
  • 场景结果:对象A标记为Gray.

场景四

  • 场景内容:对象A被一个栈对象B删除引用,成为另一个堆对象C的下游。
  • 场景结果: 对象A依旧标记为Black堆对象C的最相邻下游节点标记为Gray.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值