Go 语言GC(垃圾回收)的工作原理

news/2024/12/22 7:35:27/

Go语言的垃圾回收(Garbage Collection,简称GC)机制是一种自动的内存管理方法,它负责自动释放不再使用的内存,以避免内存泄漏和碎片化。Go语言的GC工作原理主要基于标记-清除(mark-and-sweep)算法,并经过多次优化,以在程序运行时有效地完成内存管理任务。以下是Go语言GC工作原理的详细解释:

一、标记-清除算法

  1. 标记阶段

    • GC从根对象(如全局变量、活跃的goroutines和栈上的变量)开始,递归地遍历所有可达对象。
    • 遍历过程中,将所有可以被访问到的对象标记为活跃(即仍然在使用的对象)。
  2. 清除阶段

    • 遍历所有对象,清除未被标记的对象(不再可达的对象),并回收其占用的内存。

二、三色标记法

为了优化标记过程,Go语言使用了三色标记法。这种方法将对象分为三种颜色:白色、灰色和黑色,以控制标记过程。

  1. 白色对象:潜在的垃圾,表示还未搜索到的对象,其内存可能会被垃圾收集器回收。
  2. 灰色对象:活跃的对象,表示正在搜索但还未搜索完的对象,因为存在指向白色对象的外部指针,垃圾收集器会扫描这些对象的子对象。
  3. 黑色对象:活跃的对象,表示搜索完成的对象,包括不存在任何引用外部指针的对象以及从根对象可达的对象。

标记过程从根对象开始,将所有对象初始化为白色。然后,从根对象出发,逐步把所有可达的对象变成灰色,再逐步将灰色对象及其可达对象标记为黑色。最终,所有的白色对象都是不可达对象,即垃圾对象。

三、并发垃圾回收

Go语言的垃圾回收是并发的,意味着它能够在程序运行时自动进行垃圾回收,不会暂停整个程序。这种设计减少了“停顿”时间,使其对性能的影响更小。

  1. 并发标记:在标记阶段,GC与用户程序并发执行,以减少程序性能的影响。
  2. 写屏障:为了确保并发标记的正确性,Go语言使用了写屏障技术。写屏障是一种在用户程序读取对象、创建新对象以及更新对象指针时执行的一段代码。它用于确保在并发标记过程中,黑色对象不会直接指向白色对象,从而维护三色不变性。

四、垃圾回收过程

Go语言的垃圾收集可以分成清除终止、标记、标记终止和清除四个不同阶段:

  1. 清理终止阶段:暂停程序,所有的处理器在这时会进入安全点。如果当前垃圾收集循环是强制触发的,还需要处理还未清理的内存管理单元。
  2. 标记阶段:将状态切换至_GCmark、开启写屏障、用户程序协助(Mutator Assists)并将根对象入队;恢复执行程序,标记进程和用于协助的用户程序会开始并发标记内存中的对象。
  3. 标记终止阶段:暂停程序、将状态切换至_GCmarktermination并关闭辅助标记的用户程序;清理处理器上的线程缓存。
  4. 清理阶段:将状态切换至_GCoff开始清理阶段、初始化清理状态并关闭写屏障。

五、触发垃圾回收的条件

  1. 内存使用量:当内存使用量超过一定的阈值时,垃圾回收会被触发。Go使用环境变量GOGC来调整垃圾收集的目标百分比,默认值为100,即当已分配的内存大小与垃圾回收前的内存使用量的比例达到100%时,会触发GC。
  2. 分配新对象:在分配新的对象时,Go会检查当前的内存使用情况,并可能触发垃圾回收,以确保有足够的内存空间。
  3. 手动触发:开发者可以使用runtime.GC()函数在代码中手动触发垃圾回收。

综上所述,Go语言的垃圾回收机制通过标记-清除算法和三色标记法来识别并回收不再使用的内存空间。同时,通过并发垃圾回收和写屏障技术来优化性能并确保正确性。


http://www.ppmy.cn/news/1557138.html

相关文章

Java-29 深入浅出 Spring - IoC 基础 启动IoC容器的方式 Java方式与Web(XML、配置)方式

点一下关注吧!!!非常感谢!!持续更新!!! 大数据篇正在更新!https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了: MyBatis&#xff…

硬盘接口模式sata与ahci区别, U盘UEFI GPT与Legacy 启动项区别,硬盘格式MBR和gpt的区别

一。SATA和AHCI的主要区别在于它们的功能、接口类型和性能。‌ 功能和性能 SATA‌:Serial ATA(SATA)是一种硬盘接口标准,主要用于连接存储设备(如硬盘)到主机(如主板)。它经历了多个…

QMainwindow的鼠标跟踪事件不触发问题

一、无边框窗口实现代码 1.1 头文件 class EtcTestTool : public QMainWindow {Q_OBJECTpublic:EtcTestTool(QWidget *parent Q_NULLPTR); private:void InitialUi();//... protected:void mousePressEvent(QMouseEvent*event)override;void mouseReleaseEvent(QMouseEvent*…

智能座舱进阶-应用框架层-Jetpack主要组件

Jetpack的分类 1. DataBinding:以声明方式将可观察数据绑定到界面元素,通常和ViewModel配合使用。 2. Lifecycle:用于管理Activity和Fragment的生命周期,可帮助开发者生成更易于维护的轻量级代码。 3. LiveData: 在底层数据库更…

2024年云计算的发展趋势如何?

2024年云计算的发展趋势 在这个瞬息万变的科技时代,你是否也曾想过,云计算的发展究竟对我们每一个人意味着什么?它不仅是存储和计算能力的提升,更是整个行业的未来构建与转型之道。接下来,我们将一起探索2024年云计算…

Linux创建普通用户和修改主机名

创建修改用户名和用户组 工作组相关命令 功能命令说明切换用户su username注销用户logout新建用户adduser username 创建用户并分配到用户组useradd -g test username 设置用户密码passwd username查看某一用户w username查看登录用户w查看登陆用户并显示IPwho查看登录历史…

重拾设计模式--适配器模式

文章目录 适配器模式(Adapter Pattern)概述适配器模式UML图适配器模式的结构目标接口(Target):适配器(Adapter):被适配者(Adaptee): 作用&#xf…

课上测试:商用密码标准实现

文章目录 完成下面任务(29分)1 在 Ubuntu 或 openEuler 中完成任务(推荐openEuler)2 简述 GM/T0009 4种数据转换的功能,根据你的理解,每种转换功能给出至少一个例子 (8分)3 参考课程…