Go语言中的GC

  1. Go的垃圾回收机制

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

简单的说,垃圾回收的核心就是标记出哪些内存还在使用中(即被引用到),哪些内存不再使用了(即未被引用),把未被引用的内存回收掉,以供后续内存分配时使用。

垃圾回收开始时从root对象开始扫描,把root对象引用的内存标记为"被引用",考虑到内存块中存放的可能是指针,所以还需要递归的进行标记,全部标记完成后,只保留被标记的内存,未被标记的全部标识为未分配即完成了回收。

  1. 垃圾回收触发时机

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

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

  1. 垃圾回收算法

(1)引用计数:对每个对象维护一个引用计数,当引用该对象的对象被销毁时,引用计数减1,当引用计数器为0时回收该对象。

(2)标记-清除:从根变量开始遍历所有引用的对象,引用的对象标记为"被引用",没有被标记的进行回收。

(3)分代收集:按照对象生命周期长短划分不同的代空间,生命周期长的放入老年代,而短的放入新生代,不同代有不能的回收算法和回收频率。

Golang中的垃圾回收主要应用三色标记法,GC过程和其他用户goroutine可并发运行,但需要一定时间的STW(stop the world),STW的过程中,CPU不执行用户代码,全部用于垃圾回收,这个过程的影响很大,Golang进行了多次的迭代优化来解决这个问题,下面我们就来探讨一下这个问题。

  1. GC的分析工具

GC的分析工具有:

go tool pprof
go tool trace
go bulid -gcflags = “-m”
GODEBUG=“gctrace=1”

最常用的是GODEBUG=“gctrace=1”,下图中展示的是采用GODEBUG=“gctrace=1分析GC的情况。

  1. 总结

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

作者:孔祥宇

猜你喜欢

转载自blog.csdn.net/ekcchina/article/details/130710298