Go 内存优化与垃圾收集( 四 )


由于频繁调用垃圾收集器,应用程序的运行时可能会无限增加,从而消耗应用程序的CPU时间 。
这种行为被称为死亡螺旋[7],可能导致应用程序性能下降,与OOM错误不同 , 这种问题很难检测和修复 。
这正是GOMEMLIMIT机制作为软限制起作用的原因 。
Go不能100%保证GOMEMLIMIT指定的内存限制会被严格执行 , 而是会允许使用超出限制的内存,并防止频繁调用垃圾收集器的情况 。
为了实现这一点,需要对CPU使用设置限制 。目前,这个限制被设置为所有处理器时间的50%,CPU窗口为2 * GOMAXPROCS秒 。
这就是为什么我们不能完全避免OOM错误,而是会将其推迟到很久以后发生 。
在哪里应用GOMEMLIMIT和GOGC如果默认垃圾收集器设置在大多数情况下是足够的,那么带有GOMEMLIMIT的软内存管理机制可以使我们避免不愉快的情况 。
使用GOMEMLIMIT内存限制可能有用的例子:

  • 在内存有限的容器中运行应用程序时,最好将GOMEMLIMIT设置为保留5-10%的可用内存 。
  • 在运行资源密集型库或代码时,对GOMEMLIMIT进行实时管理是有好处的 。
  • 当在容器中以脚本形式运行应用程序时(意味着应用程序在一段时间内执行某些任务,然后终止),禁用垃圾收集器但设置GOMEMLIMIT可以提高性能并防止超出容器的资源限制 。
避免使用GOMEMLIMIT的情况:
  • 当程序已经接近其环境的内存限制时,不要设置内存限制 。
  • 在无法控制的执行环境中部署时,不要使用内存限制,特别是在程序的内存使用与其输入数据成正比的情况下,例如CLI工具或桌面应用程序 。
如上所述,通过深思熟虑的方法,我们可以管理程序中的微调设置,例如垃圾收集器和GOMEMLIMIT 。然而,仔细考虑应用这些设置的策略无疑非常重要 。
参考资料
  • [1]Memory Optimization and Garbage Collector Management in Go: https://betterprogramming.pub/memory-optimization-and-garbage-collector-management-in-go-71da4612a960
  • [2]A Guide to the Go Garbage Collector: https://tip.golang.org/doc/gc-guide
  • [3]mgc.go: https://go.dev/src/runtime/mgc.go
  • [4]malloc.go: https://go.dev/src/runtime/malloc.go
  • [5]mgc.go: https://go.dev/src/runtime/mgc.go
  • [6]48409-soft-memory-limit.md: https://Github.com/golang/proposal/blob/master/design/48409-soft-memory-limit.md
  • [7]Soft Memory Limit Death Spirals: https://github.com/golang/proposal/blob/master/design/48409-soft-memory-limit.md#death-spirals

【Go 内存优化与垃圾收集】


推荐阅读