golang的gc流程

Bomb_ · · 1844 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

一 经典的GC算法
  1. 引用计数(reference counting)
  2. 标记-清扫(mark & sweep)
  3. 复制收集(Copy and Collection)
二 标记-清扫(mark & sweep)算法

golang的gc算法主要是基于标记-清扫(mark & sweep)算法,在了解go的gc先了解一下传统的标记-清扫(mark & sweep)算法。
这个算法有2个操作

  • 标记
  • 清除

mark and sweep算法在执行的时候,需要程序暂停( stop the world ),大致的步骤是:

  1. stop the world 暂停程序执行
  2. 找到root根对象可以到达的对象做好标记
  3. 清除没有做标记的对象
  4. start the world 开始程序执行

三 golang的清除流程 (三色并发标记) 分4个阶段

第一个阶段 gc开始 (stw)

  1. stop the world 暂停程序执行
  2. 启动标记工作携程( mark worker goroutine ),用于第二阶段
  3. 启动写屏障
  4. 将root 跟对象放入标记队列(放入标记队列里的就是灰色)
  5. start the world 取消程序暂停,进入第二阶段

第二阶段 marking(这个阶段,用户程序跟标记携程是并行的)

  1. 从标记队列里取出对象,标记为黑色
  2. 然后检测是否指向了另一个对象,如果有,将另一个对象放入标记队列
  3. 在扫描过程中,用户程序如果新创建了对象 或者修改了对象,就会触发写屏障,将对象放入单独的 marking队列,也就是标记为灰色
  4. 扫描完标记队列里的对象,就会进入第三阶段

第三阶段 处理marking过程中修改的指针 (stw)

  1. stop the world 暂停程序
  2. 将marking阶段 修改的对象 触发写屏障产生的队列里的对象取出,标记为黑色
  3. 然后检测是否指向了另一个对象,如果有,将另一个对象放入标记队列
  4. 扫描完marking队列里的对象,start the world 取消暂停程序 进入第四阶段

第四阶段 sweep 清楚白色的对象
到这一阶段,所有内存要么是黑色的要么是白色的,清楚所有白色的即可
golang的内存管理结构中有一个bitmap区域,其中可以标记是否“黑色”

四 golang gc 的触发
  • 触发内存的阀值,内存达到上次gc后的2倍
  • 2分钟
  • 手动触发

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:Bomb_

查看原文:golang的gc流程

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1844 次点击  
加入收藏 微博
1 回复  |  直到 2020-07-24 11:19:02
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传