Go语言带你一起飞--Go的垃圾回收

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/YSC1123/article/details/79961225

        相信熟悉某一门编程语言的攻城狮们,对它的垃圾回收一定不陌生,是不是曾经不止一次地受到jvm给准备的oom彩蛋!就问你:惊不惊喜,惊不惊悚?!

      前段时间自己研究了一下Go语言,时隔这么些天,总该有这么一个机会将自己对Go的认知做一下沉淀,但相对于之前的系列博客,脑门一热打算先从它的垃圾回收开始整理,这里将结合一些java中的垃圾回收算法来做对比;对于java,我们可以从多个角度来看它的垃圾回收算法:

▶ 按照基本回收策略来分,有引用计数、标记-清除、复制、标记-整理

▶ 按照分区对待的方式来分,有增量收集和分代收集两种;

▶ 按照系统线程来分,有串行收集和并行收集,并发收集三种;【详情见:jvm调优总结(2)

      在Go中的垃圾回收算法和jvm的垃圾回收算法一样,也是从“stop the world”开始的,并且Go中的GC是固定每分钟执行一次,而每次GC的消耗时间是与垃圾回收的对象数量相关的,垃圾回收时会扫描需要回收的内存区域,如果发现对象的内容汇总包含指针,就会递归地进行扫描;所以从一定程度上,Go中的垃圾回收更偏向于标记-清除算法;

     在Go的1.3版本开始对Go的gc性能进行持续的改进和优化,在该版本中,Go runtime分离了mark和sweep的操作,和之前版本一样,在gc之前需要先暂停所有任务并启动mark(stop the world),mark 完之后马上重新启动被暂停的任务,然后让sweep的任务和普通协程(比线程粒度更小的单位一样并行的和其他任务一起执行;

    在之后的1.4版本没有对GC做太多变更,只是将之前很多的原生c语言变换为Go语言来实现,对于go来说这次的变动可以更好更精确地实现gc;因为C语言在实现GC时不能获取到内存的对象信息,因此无法区分普通变量和指针;

    1.5版本中,改进的主要目标是减少延迟,因此实现的垃圾回收器是“非分代、非移动、并发的、三色的标记清除垃圾收集器”,而三色标记法的mark操作是可以渐进执行的而不需要每次都扫描整个内存空间,进而减少stop the world的时间。

     从整体上来讲,go语言中的GC有了很大的改进,但是还需要在优化的路上继续前进;



阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页