当前位置: 主页 > 建站知识

Go Ballast 是一个性能优化工具,可让内存管理更加高效。关于优化 Go GC 的方法,你知道有哪些呢?

发布时间:2024-06-26 14:46   浏览次数:次   作者:zoc7RcITctunhMtq7EzA
通常做法是改变垃圾回收的节奏,从而调整垃圾回收的触发频率。

设置 GOGC 为 调用 debug.SetGCPercent()

这两种方式的原理和效果完全相同,GOGC 的默认值为100,即下一次 GC 触发时,堆的大小将是上一次 GC 之后堆大小的两倍。在进行 GC 时,GO 会使用标记-清除的方式,即进行全量遍历变量进行标记,标记完成后再执行清除操作,将被标记为白色的对象进行垃圾回收。需要注意的是,这里的内存回收仅仅是将内存标记为可归还给操作系统,并不会立即进行回收,这也是导致你看到 Go 应用程序的内存占用保持较高水平的原因。在 Go 程序的整个垃圾回收过程中,会发生整个程序的暂停(STW),Go 垃圾回收的时间主要取决于标记阶段花费的时间长短,清除阶段则非常迅速。调整 GOGC 的弊端包括以下几点:1. GOGC 的设置方式缺乏精确性。设置 GOGC 实际上是我们常用的 Go 垃圾回收优化方式,但大多数情况下并不需要调整 GOGC 就能满足需求。一方面是因为程序可能不够内存密集,另一方面是由于 GOGC 的比率设定不够准确,难以精确控制所需的垃圾回收触发阈值。2. 如果将 GOGC 设置得过小,就会频繁触发垃圾回收(GC),导致大量的 CPU 时间被浪费在无效的垃圾回收上,这会明显影响程序的性能。举个例子,就是 API 接口时常性的延迟会导致结果发生周期性的耗时变化。在这种情况下,你可以抓取 CPU 性能文件来检查,大部分时间都被用于垃圾回收相关的处理。

根据上面的图表,这次 prometheus 的查询显示大部分 CPU 资源都被用在了垃圾回收操作上。在生产环境中也经常发生这种情况,因为设置的GOGC太小,导致太多的资源被用于垃圾回收。

3. 有些程序的内存消耗较低,容易触发 GC

对 API 接口响应时间敏感的业务,若 GOGC 使用默认值,则可能会经历接口响应时间周期性波动。为什么会这样呢星空体育官方?由于这种接口本身占用较少内存,在每次垃圾回收后,占用的内存较少。如果根据上次垃圾回收后堆(heap)的大小设定 GOGC 为其两倍的话,实际上就很容易触发这个阈值,造成接口因垃圾回收而导致额外开销的情况。

4. GOGC 的大小设置很大,有时可能会导致 OOM 的发生

如何进行适当的调整呢星空体育下载?增大GOGC的设置是否有利于提高性能呢?这种做法可以减少GC触发的频率,但需要将该数值设置得非常大才能见效。这种情况会带来问题,如果GOGC设置过大,当这些接口突然受到大量流量时,由于长时间未触发GC,可能会导致内存溢出。在这种情况下,GOGC 并不适用于某些情景,是否有一种方法可以精准控制内存,以便在达到 10GB 的倍数时准确控制 GC 呢?需要出场的是Go语言调参内存的设置。Go ballast 是指初始化一个庞大的切片,在整个 Go 应用程序的生命周期中持续存在。

def main() {   ballast := make([]byte, 10*1024*1024*1024) // 10G       // 做 一些 事情      runtime.KeepAlive(ballast) } 

以上代码初始化了一个 ballast,使用 runtime.KeepAlive 来确保 ballast 不被 GC 回收星空体育官网。通过利用这种特性,可以确保只有在达到10G时才会触发GC,从而更精确地控制GO GC的触发时机。

也许你会有一个疑问,这里创建了一个大小为 10G 的数组,难道不会占用 10G 的物理内存吗星空体育APP?实际上答案是无法知道的。import语句用于将所需的包导入到程序中。在这段代码中,多个包被导入,如runtime、math和time。在main函数中,创建一个名为ballast的字节切片。如果需要一秒钟大约1秒钟的内存访问,您可以使用以下代码作为参考: \n```go\nif err := syscall.(time.Duration(math.MaxInt64)); err != nil { return err} \nruntime.KeepAlive(p) \n``` \n请确保您的系统具有足够的内存和资源来执行此操作。使用vsz,按照rss排序,将numfmt应用到第5个字段,从1024单位转换到iec后应用到第6个字段,列出egrep匹配的进程,其中包括%MEM,COMMAND,PID,MAJFL,MINFL,RSS和VSZ。这个输出是在CentOS Linux release 7.9上验证过的。我们发现实际物理内存占用的 RSS 为344兆字节,但虚拟内存 VSZ 占用了10吉字节。如果我们怀疑接口的耗时增加是由于频繁的GC触发引起的,我们应该如何确认呢?如果怀疑我们接口调用延迟是由于频繁的 GC 触发引起的,要怎么确定呢星空体育官网?最先想到的是定期使用 pprof 进行分析,这种方法虽然可行,但比较繁琐。可以根据 GC 触发时间来绘制曲线图,这个时间可以通过查询 runtime.Memstats 的 LastGC 字段来获取。

生产环境验证 绿线调整前的GOGC值为30 黄线调整后GOGC默认值,ballast=100G

在相同流量和压力下,可以明显看出ballast的表现更佳。

Go Ballast 是一个性能优化工具,可让内存管理更加高效。关于优化 Go GC 的方法,你知道有哪些呢?


在这篇文章中仅对 Go 负载均衡的使用进行了简要介绍,Go 负载均衡是被官方广泛认可的解决方案,更多细节请见问题编号 23044[1]。许多开源软件,比如tidb[2]和cortex[3],都已经引入了go ballast功能星空体育下载。如果你的程序受制于GOGC问题或者出现周期性的耗时波动,不妨考虑尝试go ballast。毫无疑问强烈建议您浏览twitch.tv的这篇文章[4],相信会让您对GOGC以及漂亮的使用有更深入的了解。{主体}{名词}{名词}


星空体育官方 星空体育下载