Go的垃圾回收(GC),详细总结

1. GC的简介

GC(Garbage Collection),垃圾回收,分配在堆上的内存不会再使用时,Go语言将会自动回收分配在堆上的内存,从而避免系统的内存被占满。Go的自动回收内存的特性,使得Go程序开发者可以更加专注于代码的效率,很大程度上避免了内存的泄漏。
Go语言中GC思想
Go中采用最简单的“标记-清除”,“标记有用的对象,清除无用的对象”,采用广度优先搜索算法,从根集合出发,进行可达性分析,标记有用对象。

2. 标记的开始:GC的root set (根集合)

根集合是GC在标记过程中最先检查的对象。主要包括:

  • 全局变量:在程序编译期间就能确定,全局变量存在于程序的整个生命周期。
  • 执行栈:Go语言中协程是分配在堆上,每个协程都含有自己的执行栈。
  • 寄存器:寄存器的值可能表示一个指针,这些指针可能指向另一块内存空间。
    GC根集合

3 串行GC(STW)

Go语言的老版本采用的是串行GC。首先根据可达性分析法,采用广度优先搜索算法,先从根集合出发寻找被应用的对象,对内存标记。通过下图可知,J内存块并未被标记,说明J内存块可以进行垃圾回收。
串行GC的**缺点:**需要stop the world (STW)暂停所有的业务,对性能的影响较大,难以支持高并发。
标记过程

4.并发GC

为了减少GC对性能的影响,Go现在的版本支持并发进行垃圾回收。采用的标记法为三色标记法。

4.1 三色标记法

三色标记法:

  • 黑色:表示有用的对象,并且已经分析扫描完
  • 灰色:有用,但是未分析扫描完
  • 白色:暂时无用

三色标记法的步骤:

  • 第一,首先一开始所有的对象都是白色的,从根节点出发,将根节点可达的对象置为灰色。
  • 第二,然后分析灰色节点指向的节点,将灰色节点指向的节点置为灰色节点,分析完一个灰色节点的所有指向后将灰色该灰色节点置为黑色,表示该节点有用,并且已经扫描完。
  • 第三,重复步骤二,直到没有节点的颜色发生变化,剩下的白色节点就是无用的节点。

三色标记法主要用于解决并发GC问题,但是如果只有三色标记法不做其他处理的话,在进行GC的过程中如果有元素的删除,或者元素的插入,或者元素的指向关系发生变化的时候,可能会出现误清除对象的问题。解决办法:在进行增删改的时候加入屏障

4.2 插入屏障

在并发标记中,一个已经置为黑色的对象A(表示已经扫描分析过了),这时候插入一个对象C,并将A对象指向C对象,在扫描完后C对象仍然是白色的,可能会出现误清除。在插入一个对象后(例如插入对象C),将该对象置成灰色,然后继续扫描,可以防止插入的新元素被误清除。

4.3 删除屏障

在进行并发标记的过程中,会存在某些对象被删除(记为C),被删除后的对象又被别的已经是黑色的对象进行连接。这时候,可能出现在全部扫描完后,C对象仍然是白色,会被误清除。加入删除屏障的时候可以避免该问题的发生,删除屏障即在进行删除操作的时候,将被删除的对象置为灰色,这样在后续的扫描中将,如果该对象后续有别的对象进行指向则不会被删除,若该对象不存在后续的指向,则将会被清除。

4.4 混合屏障

**Go的GC使用的是混合屏障,在进行插入和删除的操作的时候将对象置为灰色。**这样就可以实现高并发的垃圾回收,业务和GC可以同时进行。注意:GC还是会停止业务,在启动屏障的时候会暂停业务一小会。

5. GC的触发时机

Go语言中有三种GC的触发时机:

  • 系统的定时触发:如果两分钟内没有触发GC,则会每隔两分钟进行触发一次GC。
  • 用户显示调用:用户调用runtime.GC方法,进行强制触发
  • 申请内存时触发:给对象申请堆空间的时候,可能会触发GC,调用mallocgc的方法。
    mallocgc方法

6. GC的优化原则

从上述的GC的调用时机难以优化GC,GC的优化原则是优化代码的结构,减少在堆上产生垃圾
减少在堆上产生垃圾的方法:

  • 内存池化,内存池,例如channel中采用环形缓存,环形缓存可以一直复用,可以减少垃圾回收
  • 减少逃逸:优化代码,尽可能在栈上分配内存。
  • 使用空结构体:空结构体不占用内存空间。

7. GC的分析工具

GC的分析工具有:

  • go tool pprof
  • go tool trace
  • go bulid -gcflags = “-m”
  • GODEBUG=“gctrace=1”
  • 最常用的是GODEBUG=“gctrace=1”,下图中展示的是采用GODEBUG=“gctrace=1分析GC的情况。

GC分析情况

8. 总结

  1. Go语言可以自动回收堆上分配的内存,并且可以实现并发进行GC,性能较优
  2. Go语言采用的标记方法为三色标记法,并且为了进行并发GC,采用了混合屏障,有效的应对GC过程中的插入和删除操作。
  3. GC有三个触发的时机,分别是,定时触发、用户显示调用触发、申请内存时触发。
  4. GC的优化原则,尽量减少在堆上分配垃圾,内存池化、减少逃逸,使用空结构体。
  5. GC的分析中最常用的命令时GODEBUG=“gctrace=1
  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值