在GO中增加堆大小

ia2d9nvy  于 2023-06-03  发布在  Go
关注(0)|答案(3)|浏览(240)

有没有办法让GO运行时使用更大的堆?运行GO 1.5
我的GO进程目前在GC中花费了34%的时间,但它只使用了可用系统内存的1/3。
我知道ulimit可以用来限制最大堆大小。我将ulimit设置为~ 16 GB(ulimit -v 17179869184),但堆大小从未超过5GB。
使用GODEBUG=gctrace=1,我可以看到很高的GC开销(34%):

20160719-220359.169294 :: gc 665 @5484.983s 34%: 3.3+2504+188+1635+8.0 ms clock, 26+2504+0+26950/3271/3.5+64 ms cpu, 4825->4964->2623 MB, 4948 MB goal, 8 P
20160719-220406.322354 :: gc 666 @5492.411s 34%: 2.9+212+2111+1749+8.3 ms clock, 23+212+0+25010/3496/146+67 ms cpu, 4846->4990->2657 MB, 4970 MB goal, 8 P
20160719-220413.703514 :: gc 667 @5499.452s 34%: 4.4+4411+0.021+0.25+8.4 ms clock, 35+4411+0+29365/0.054/38+67 ms cpu, 4908->5022->2618 MB, 5025 MB goal, 8 P
mbzjlibv

mbzjlibv1#

您可以使用GOGC环境变量来控制它。这是一个百分比:将其设置为200,Go运行时将使用两倍的内存。
[this被埋在评论里;我把它作为答案显示出来]
更新:在https://github.com/golang/go/issues/23044中有不同技术的详细讨论,包括提到“镇流器”技术。

tzdcorbm

tzdcorbm2#

Golang文档描述了GOGC:
GOGC变量设置初始垃圾收集目标百分比。当新分配的数据与上次收集后剩余的实时数据的比率达到此百分比时,将触发收集。默认值为GOGC=100。设置GOGC=off将完全禁用垃圾收集器。
GOGC有一个最佳值,它取决于运行Go应用程序的应用程序和系统。你可以在这个blog和这个one中阅读更多。
您可以尝试不同的值并查看对性能的影响,或者使用像Optimizer Studio这样的免费工具,它会自动找到最佳的GOGC值。

vmdwslir

vmdwslir3#

我知道ulimit可以用来限制最大堆大小
实际上,从可能的Go 1.19(2022年第四季度)开始,这将不是唯一的方法。
来自golang/go issue 48409 "Proposal: Soft memory limit"(2022年5月刚刚登陆,commit f01c20b实现了它的design document
一个新的选项,通过对Go语言使用的内存总量设置软内存限制来调整Go语言垃圾收集器的行为。
此选项有两种类型:

  • 一个新的runtime/debug函数,名为SetMemoryLimit;
  • GOMEMLIMIT环境变量。

总之,运行时将通过限制堆的大小以及更积极地将内存返回到基础平台来尝试维护此内存限制。
这包括一种帮助减轻垃圾收集死亡螺旋的机制。

**最后,通过设置GOGC=off,Go运行时将始终将堆增长到满内存限制。

这个新选项使应用程序能够更好地控制其资源经济。它使用户能够:

  • 更好地利用他们已有的记忆,
  • 自信地降低他们的记忆极限,知道围棋会尊重他们,
  • 避免不受支持的垃圾收集调优形式。

golang/go issue 58106明确指出:
增加GOMEMLIMIT的另一种方法是,一旦接近限制,就切换到基于GOGC的GC触发器。
这实际上只是一个较软的限制,但根据内存而不是CPU使用率来定义(这可能噪音较小)。
您可以在任何给定时间计算“有效”GOGC值,如下所示:
(/gc/heap/goal:bytes) / (/gc/heap/live:bytes + /gc/scan/stack:bytes + /gc/scan/globals:bytes) * 100 - 100
并将其与您的目标最小值GOGC进行比较,例如10。如果该值低于10,则将SetGCPercent设置为10,并将GOMEMLIMIT设置回MaxInt64

相关问题