当前位置: 首页 > article >正文

Go的垃圾回收(GC)机制

Go 的垃圾回收(GC)机制

Go 语言的垃圾回收机制是其运行时系统的重要组成部分,负责自动管理内存,避免内存泄漏。Go 的 GC 机制经历了多次演进,从最初的标记清除法到现在的三色标记法,逐步优化了性能和效率。


1. GC 机制的演进

Go 的 GC 机制经历了三个主要阶段的演进:

Go 1.3 之前:标记清除法(Mark and Sweep)
  • 过程
    1. 启动 STW(Stop The World),暂停所有 Goroutine。
    2. 执行标记阶段,标记所有可达对象。
    3. 执行清除阶段,回收未被标记的对象。
    4. 停止 STW,恢复 Goroutine 运行。
  • 缺点
    • STW 时间较长,影响程序性能。
    • 效率较低,尤其是在堆内存较大时。
Go 1.5:三色标记法
  • 改进
    • 使用三色标记法(白色、灰色、黑色)进行并发标记。
    • 堆空间启用写屏障,栈空间不启用。
    • 标记完成后需要重新扫描栈空间(需要 STW)。
  • 优点
    • 减少了 STW 时间,提高了并发性能。
  • 缺点
    • 重新扫描栈空间仍需要 STW。
      在这里插入图片描述
Go 1.8:混合写屏障
  • 改进
    • 引入了混合写屏障机制,进一步减少 STW 时间。
    • 栈空间不再重新扫描,所有栈对象初始标记为黑色。
    • 堆空间启用写屏障,确保并发标记的正确性。
  • 优点
    • 几乎不需要 STW,大大提高了程序性能。

2. 三色标记法

三色标记法是 Go GC 的核心算法,通过将对象标记为三种颜色(白色、灰色、黑色)来实现并发标记。

标记过程
  1. 初始状态
    • 所有对象标记为白色。
  2. 根节点扫描
    • 从根节点(如全局变量、栈对象)出发,将可达对象标记为灰色。
  3. 并发标记
    • 遍历灰色对象,将其引用的白色对象标记为灰色,自身标记为黑色。
    • 重复此过程,直到没有灰色对象。
  4. 清除阶段
    • 回收所有白色对象。
颜色含义
  • 白色:未被访问的对象,可能被回收。
  • 灰色:已被访问,但其引用的对象未被完全扫描。
  • 黑色:已被访问,且其引用的对象已被完全扫描。

3. 写屏障机制

写屏障是 Go GC 实现并发标记的关键技术,用于在并发标记过程中防止对象被误回收。

插入屏障
  • 作用:当堆中的黑色对象引用白色对象时,将白色对象标记为灰色。
  • 优点:防止黑色对象引用的白色对象被误回收。
删除屏障
  • 作用:当堆中的灰色对象删除对白色对象的引用时,将白色对象标记为灰色。
  • 优点:防止因引用删除而导致白色对象被误回收。
混合写屏障(Go 1.8)
  • 规则
    1. GC 开始时,将栈上的对象全部标记为黑色。
    2. GC 期间,任何在栈上创建的新对象均为黑色。
    3. 被删除的对象标记为灰色。
    4. 被添加的对象标记为灰色。
  • 优点
    • 栈空间无需重新扫描,减少了 STW 时间。
    • 堆空间的写屏障确保了并发标记的正确性。

4. 未来优化方向

Go 的 GC 机制仍在不断优化,未来的改进方向可能包括:

  • 更低的延迟:进一步减少 STW 时间,提高程序的响应速度。
  • 更高的吞吐量:优化标记和清除算法,提高 GC 的执行效率。
  • 自适应 GC:根据程序的内存使用情况动态调整 GC 策略。

初始状态
所有对象标记为白色
根节点扫描
将可达对象标记为灰色
并发标记
遍历灰色对象
将引用的白色对象标记为灰色
自身标记为黑色
是否还有灰色对象?
清除白色对象

http://www.kler.cn/a/517365.html

相关文章:

  • java读取设置pdf属性信息
  • 使用 Pipeline 提高 Redis 批量操作性能
  • 二叉树(了解)c++
  • 单值二叉树(C语言详解版)
  • 考研机试题:打印日期
  • tomcat的accept-count、max-connections、max-threads三个参数的含义
  • 如何在 Spring Boot 中实现自定义属性
  • 计算机视觉算法实战——驾驶员安全带检测
  • 2022年全国职业院校技能大赛网络系统管理赛项模块A:网络构建(样题8)
  • 深入理解 HTML DOM:文档对象模型详解
  • windows系统改变vscode的插件位置
  • 【Bug 记录】el-sub-menu 第一次进入默认不高亮
  • 【17】组织测试(一)
  • 组件封装-List
  • kettle与Springboot的集成方法,完整支持大数据组件
  • PySide(PyQT)进行SQLite数据库编辑和前端展示的基本操作
  • 使用 Git LFS 管理大文件基本简介
  • Java开发的商城系统怎样
  • Consul持久化配置报错1067---consul_start
  • ansible自动化运维实战--fetch、cron和group模块(5)
  • 【Uniapp-Vue3】uni-icons的安装和使用
  • 使用Mermaid和AI画流程图
  • vue2和vue3指令
  • [操作系统] 深入进程地址空间
  • 机器学习数据集来源
  • Sourcetree:一款高效便捷的Git版本控制客户端