专栏首页咻咻ing深入理解Go GC
原创

深入理解Go GC

什么是GC

GC(Garbage Collection)在计算机科学中是一种自动的存储器管理机制。当一个计算机上的动态存储器不再需要时,就应该予以释放,以让出存储器,这种存储器资源管理,称为GC。GC可以让程序员减轻许多负担,也减少程序员犯错的机会。

简单地说,GC是在后台运行一个守护线程,它的作用是在监控各个对象的状态,识别并且丢弃不再使用的对象来释放和重用资源。

Go GC的演进

  • go1.3以前的版本使用标记-清理方式,整个过程都要STW。
  • go1.3版本分离了标记和清理操作,标记过程STW,清理过程并发执行。
  • go1.5版本使用三色标记法。标记和清理并发执行,但是标记开始前后阶段需要STW来准备和re-scan。
  • go1.8版本引入混合屏障rescan来降低mark termination时间
  • go1.12版本使用非分代的并发的三色标记清理算法,配合写屏障和混合GC。

三色标记法

  1. 初始时,所有对象都在白色集合中。
  2. 从GC Roots出发扫描所有根对象,将它们引用的对象放入灰色集合中。
  3. 从灰色集合中获取对象,将本对象引用到的对象放入灰色集合中,将本对象放入黑色集合。
  4. 重复步骤3,直至灰色集合为空时,白色集合中的对象即为需要清理的对象。

Go GC的过程

Go GC分为Mark和Sweep两大阶段。Mark阶段又分为三个步骤,其中两个会有STW,另一个会有延迟。

Mark阶段的三个步骤:

  1. Mark Setup阶段-STW

在gc开始时,必须执行的第一个动作是打开写屏障(Write Barrier)。写屏障的目的是允许垃圾收集器在垃圾收集期间维护堆上的数据完整性,因为垃圾收集器和应用程序将并发执行。

为了打开写屏障,必须停止每个goroutine。此动作通常非常快,平均在10到30微秒之内完成。

  1. Marking阶段-并发执行

一旦写屏障打开,垃圾收集器就开始标记阶段。垃圾收集器所做的第一件事是占用25%CPU。垃圾收集器使用Goroutines进行垃圾收集工作,. 这意味着对于一个4线程的Go程序,一个P将专门用于垃圾收集工作。

垃圾收集器首先检查所有现goroutine的堆栈,以找到堆内存的根指针。然后收集器必须从那些根指针遍历堆内存图,标记可以回收的内存。

如果垃圾收集器确定需要减慢内存分配,原本运行应用程序Goroutines会协助标记工作。应用程序Goroutine成为Mark Assist(协助标记)中的时间长度与它申请的堆内存成正比。Mark Assist有助于更快地完成垃圾收集。

垃圾收集器的一个设计目标是减少对Mark Assists的需求。如果任何本次垃圾回收最终需要大量的Mark Assist才能完成工作,则垃圾收集器会提前开始下一个垃圾收集周期。这样做可以减少下一次垃圾收集所需的Mark Assist。

  1. Mark终止-STW

一旦并发标记阶段完成,下一个阶段就是标记终止。最终关闭写屏障,执行各种清理任务,并计算下一个垃圾回收周期的目标。一直处于循环中的goroutine也可能导致stw延长(类似mark setup的情况)。

Sweep(并发清理)

标记完成后,下一阶段执行并发清理。清理阶段用于回收标记阶段中标记出来的可回收的内存。当应用程序goroutine尝试在堆内存中分配新内存时,会触发该操作。清理导致的延迟和吞吐量降低被分散到每次内存分配时。

GC触发时机

  1. 分配内存时, 当前已分配内存与上一次GC结束时存活对象的内存达到某个比例时就触发GC。
  2. sysmon检测2min内是否运行过GC, 没运行过 则执行GC。
  3. 调用runtime.GC()强制触发GC。

GC 调优

减少堆内存的分配是最好的优化方式。比如合理重复利用对象;避免string和byte[]之间的转化等。

优化努力的方向:

  1. 尽可能保持最小的堆内存。
  2. 最佳的GC频率。
  3. 保持每次垃圾收集的内存大小。
  4. 最小化每次垃圾收集的STW和Mark Assist的持续时间

最后

垃圾收集是一个很好的权衡,虽然有垃圾收集的成本,却降低了内存管理的难度。但是也不能完全依赖垃圾收集器,养成良好的内存分配习惯,有助于提高应用程序的性能和吞吐量。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 阿里无线11.11 之 Weex——关于移动端动态性的思考、实现和未来

    今天在移动端,尤其是像手机淘宝这样的 app 中,动态性问题逐渐成为一个比较棘手的问题。所谓动态性,就是把移动应用本身的灵活性、迭代更新的周期和成本优化到极致。...

    咻咻ing
  • 微信引流黑科技:手机浏览器直接唤起微信方案调研

    微信作为流量爸爸,如果能从微信引流到自己的平台,想想就开心啊!!! 微信引流的一种方式:通过手机浏览器打开某一网址,然后启动微信,并跳转到微信页面。 下面分享下...

    咻咻ing
  • 微信引流黑科技:手机浏览器直接唤起微信方案调研

    链接是个微博短链:http://t.cn/RTqAzl8。放浏览器里访问,解析出完整的地址:http://r.jpwx.kim/wb/0e7d51958ac79...

    咻咻ing
  • 看完这篇,我再也不怕面试官问垃圾收集了

    说在前面:本文的篇幅较长,看本文的时候最好先去上个厕所,先准备好一杯枸杞茶,慢慢品,本文将会讲解三种垃圾收集算法:标记-清除、复制、标记-整理算法,以及各种成熟...

    用户5546570
  • GC算法 垃圾收集器

    垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了。

    生活创客
  • jvm系列(三):GC算法 垃圾收集器

    概述 垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了。 ...

    纯洁的微笑
  • Java虚拟机(三):JVM垃圾回收机制

    垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了。

    朝雨忆轻尘
  • 垃圾回收的常见算法

    自动化的管理内存资源,垃圾回收机制必须要有一套算法来进行计算,那些是有效的对象,那些是无效的对象,对于无效的对象 就要进行回收处理。 常见的垃圾回收算...

    海仔
  • 垃圾回收的常见算法

    自动化的管理内存资源,垃圾回收机制必须要有一套算法来进行计算,那些是有效的对象,那些是无效的对象,对于无效的对象 就要进行回收处理。 常见的垃圾回收算法有 :引...

    Edison.Ma
  • 基础知识 | 每日一练(136)

    士人有百折不回之真心,才有万变不穷之妙用。立业建功,事事要从实地着脚,若少慕声闻,便成伪果;讲道修德,念念要从虚处立基,若稍计功效,便落尘情。 ...

    闫小林

扫码关注云+社区

领取腾讯云代金券