2020-03
Go的源码会被编译成二进制文件,然后直接在对应的操作系统上运行。那么,这对学习GC有什么意义呢?让我们一起看看今天的内容。
《Go垃圾回收之旅》原文链接 - https://go.dev/blog/ismmkeynote
我们先和JAVA程序做个对比:
从这个架构不难猜到,上文谈到的 运行时,Go语言是直接编译到二进制文件里的;而JAVA是在JVM里实现的。
Go的这种实现方式,主要优劣点如下:
JIT
机制,无法针对具体的运行结果进行反馈优化JIT
的优化方向很多,我这里举一个热点函数优化的例子:
JIT
发现b的输入参数一直都是某个固定值b1JIT
进行编译优化,将函数f编译成一个新函数f1JIT
就会从f1回退到f简单来说:Go程序会怎么运行,往往在编码阶段就可以预期到了;而JAVA引入的JIT
能力,可以在程序运行后,根据具体的运行情况,做针对性地优化,提升效率的同时也带了很多的不确定性。
两种实现方式各有利弊,团队可以根据实际情况自行选择。单从Go语言开发者来说,排查线上问题相对有JIT
机制的JAVA程序简单很多。
这种确定性也让Go的GC相对简单不少,方便我们的学习。
在这篇演讲中,有这么一段很有意思的描述:
Out of memory, OOMs, are tough on Go; temporary spikes in memory usage should be handled by increasing CPU costs, not by aborting. Basically if the GC sees memory pressure it informs the application that it should shed load. Once things are back to normal the GC informs the application that it can go back to its regular load.
这段话包含了Go语言的GC,在面对CPU和内存压力下的决策:
GC最直观的影响就体现在延迟上。尤其是在STW - Stop The World情况下,程序会暂停所有非GC的工作,进行全量的垃圾回收。即便整个GC只花费了1s,所有涉及到这个程序的业务调用,都会增加1s延迟;在微服务场景下,这个问题会变得尤为复杂。
而GC的方案迭代,最直观的效果就体现在这个延迟优化上。
今天我们会重点讨论Go语言GC Pacer这个概念。
《Go垃圾回收之旅》原文链接 - https://go.dev/blog/ismmkeynote
要理解透彻GC Pacer的非常困难,底层实现细节必须深入到源码。这里,我们会通过分享中的关键性描述,来思考GC Pacer的设计理念。
It is basically based on a feedback loop that determines when to best start a GC cycle.
我们聚焦到两个词:
feedback loop
反馈循环,GC Pacer是会根据实际GC情况会不断迭代、反馈的when to best start a GC cycle
强调了GC Pacer的目标 - 为了决定一个最佳启动GC的时机GC Pacer的内部原理也和它的定义非常贴切,它是根据步长来决定GC的:
简单来说,就是一种 按比例增长 的触发机制。但这个机制没有那么简单,我们看下面这段:
If need be, the Pacer slows down allocation while speeding up marking. At a high level the Pacer stops the Goroutine, which is doing a lot of the allocation, and puts it to work doing marking.
这两句描述和我们上一讲的内容对应上了 - 在一定的性能压力下,Pacer会减少内存的分配,而花更多的时间在对象的标记(marking)上,它是GC里的最耗性能的步骤。
对应到上面提到的反馈呢,也就是GC Pacer并不是单纯的一种 按比例增长 的触发机制,还有一些其余因素的影响:比如,当前这次的GC花费的CPU计算资源与标记的耗时超过了预期,表示当前整个GC存在一定压力,下次的GC的开始时间需要适当提前。
GC Pacer最近也重新做了一次大的改动,有兴趣的可以参考这篇文章:
https://go.googlesource.com/proposal/+/a216b56e743c5b6b300b3ef1673ee62684b5b63b/design/44167-gc-pacer-redesign.md
深入研究GC Pacer需要很多数学知识储备,留给有兴趣的同学自行探索了。