Golang什么时候会触发GC

Python011

Golang什么时候会触发GC,第1张

Golang采用了三色标记法来进行垃圾回收,那么在什么场景下会触发这个回收动作呢?

源码主要位于文件 src/runtime/mgc.go go version 1.16

触发条件从大方面说,可分为 手动触发 和 系统触发 两种方式。手动触发一般很少用,主要由开发者通过调用 runtime.GC() 函数来实现,而对于系统自动触发是 运行时 根据一些条件判断来进行的,这也正是本文要介绍的内容。

不管哪种触发方式,底层回收机制是一样的,所以我们先看一下手动触发,根据它来找系统触发的条件。

可以看到开始执行GC的是 gcStart() 函数,它有一个 gcTrigger 参数,是一个触发条件结构体,它的结构体也很简单。

其实在Golang 内部所有的GC都是通过 gcStart() 函数,然后指定一个 gcTrigger 的参数来开始的,而手动触发指定的条件值为 gcTriggerCycle 。 gcStart 是一个很复杂的函数,有兴趣的可以看一下源码实现。

对于 kind 的值有三种,分别为 gcTriggerHeap 、 gcTriggerTime 和 gcTriggerCycle 。

运行时会通过 gcTrigger.test() 函数来决定是否需要触发GC,只要满足上面基中一个即可。

到此我们基本明白了这三种触发GC的条件,那么对于系统自动触发这种,Golang 从一个程序的开始到运行,它又是如何一步一步监控到这个条件的呢?

其实 runtime 在程序启动时,会在一个初始化函数 init() 里启用一个 forcegchelper() 函数,这个函数位于 proc.go 文件。

为了减少系统资源占用,在 forcegchelper 函数里会通过 goparkunlock() 函数主动让自己陷入休眠,以后由 sysmon() 监控线程根据条件来恢复这个gc goroutine。

可以看到 sysmon() 会在一个 for 语句里一直判断这个 gcTriggerTime 这个条件是否满足,如果满足的话,会将 forcegc.g 这个 goroutine 添加到全局队列里进行调度(这里 forcegc 是一个全局变量)。

调度器在调度循环 runtime.schedule 中还可以通过垃圾收集控制器的 runtime.gcControllerState.findRunnabledGCWorker 获取并执行用于后台标记的任务。

Go语言主要用作服务器端开发。

其定位是用来开发“大型软件”的,适合于需要很多程序员一起开发,并且开发周期较长的大型软件和支持云计算的网络服务。

Go语言融合了传统编译型语言的高效性和脚本语言的易用性和富于表达性,不仅提高了项目的开发速度,而且后期维护起来也非常轻松。

编译器

当前有两个Go编译器分支,分别为官方编译器gc和gccgo。官方编译器在初期使用C写成,后用Go重写从而实现自举。Gccgo是一个使用标准GCC作为后端的Go编译器。

官方编译器支持跨平台编译(但不支持CGO),允许将源代码编译为可在目标系统、架构上执行的二进制文件。

go语言之所以能成为我国最火的语言,是因为编写服务端高并发程序的优势。我大中华区但凡pv,日活高点的网站,应用,谁没点这个需求。

这个领域中最优的几个:golang,erlang,rust。日常生活中人类社交是当今社会上的必然性,人们也伴随着科技时代的发展,智能电子产品的使用中也必然少不了语言输入,文字的编辑,语言转换的便利都均可来源于go语音输入法。