英文:
Increase Heap size in GO
问题
有没有一种方法可以指示GO运行时使用更大的堆空间?我正在运行GO 1.5
。
我的GO进程目前在GC中花费了34%的时间,但它只使用了可用系统内存的1/3。
我知道可以使用ulimit
来限制最大堆大小。我已将ulimit设置为约16GB(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
英文:
Is there a way howto instruct GO runtime to use larger heaps? I am running GO 1.5
.
My GO process is currently spending 34% of time in GC but it uses unly 1/3 of available systems memory.
I know ulimit
can be used to limit max heap size. I have set ulimit to ~16GB (ulimit -v 17179869184
) but the heap size never goes over 5GB.
Using GODEBUG=gctrace=1
I can see high GC overhead (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
答案1
得分: 5
你可以通过GOGC
环境变量来控制这个。它是一个百分比:将其设置为200,Go运行时将使用之前的两倍内存。
[这个信息被埋在评论中,我将其作为答案展示出来]
更新:在https://github.com/golang/go/issues/23044上有一份关于不同技术的详细讨论,其中提到了“ballast”技术。
英文:
You can control this with the GOGC
environment variable.
It is a percentage: set it to 200 and the Go runtime will use twice as much memory as before.
[this was buried in the comments; I'm making it visible as an answer]
Update: there is a detailed discussion of different techniques at https://github.com/golang/go/issues/23044, including mention of the "ballast" technique.
答案2
得分: 3
Golang文档描述了GOGC:
GOGC变量设置了初始垃圾回收目标百分比。当新分配数据与上次回收后剩余的活跃数据的比例达到该百分比时,将触发一次垃圾回收。默认值为GOGC=100。将GOGC设置为off将完全禁用垃圾回收器。
对于GOGC,存在一个最佳值,它取决于您运行Go应用程序的应用和系统。您可以在这篇博客文章和这篇博客文章中了解更多信息。
您可以尝试不同的值并观察性能的影响,或者使用像Optimizer Studio这样的免费工具,它可以自动找到最佳的GOGC值。
英文:
The Golang documentation describes GOGC:
> The GOGC variable sets the initial garbage collection target
> percentage. A collection is triggered when the ratio of freshly
> allocated data to live data remaining after the previous collection
> reaches this percentage. The default is GOGC=100. Setting GOGC=off
> disables the garbage collector entirely.
There is an optimal value for GOGC, and it depends on the application and system that you run the Go application on. You can read more in this blog and this one.
You can try different values and see the effects on performance, or use a free tool like Optimizer Studio that will find the optimal GOGC value automatically.
答案3
得分: 2
我知道ulimit
可以用来限制最大堆大小。实际上,从可能的Go 1.19版本开始(2022年第四季度),这不再是唯一的方法。
根据golang/go
问题48409“提案:软内存限制”(于2022年5月实施,使用提交f01c20b,实现其设计文档):
这个选项有两种方式:
- 一个名为
runtime/debug
的新函数SetMemoryLimit
- 一个名为
GOMEMLIMIT
的环境变量
总之,运行时将通过限制堆的大小并更积极地将内存返回给底层平台来尝试维持这个内存限制。这包括一种机制来帮助减轻垃圾回收死循环。
最后,通过设置GOGC=off
,Go运行时将始终将堆增长到完整的内存限制。
这个新选项使应用程序能够更好地控制资源经济。它使用户能够:
- 更好地利用他们已经拥有的内存
- 自信地减少内存限制,因为Go将尊重它们
- 避免不支持的垃圾回收调优形式
golang/go
问题58106明确指出:
增加GOMEMLIMIT
的另一种选择是在接近限制时切换到基于GOGC
的垃圾回收触发器。这实际上只是一个更柔和的限制,但是以内存而不是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
。
英文:
> I know ulimit
can be used to limit max heap size
Actually, starting possibly Go 1.19 (Q4 2022), this won't be the only way.
From golang/go
issue 48409 "Proposal: Soft memory limit" (which just landed in May 2022, with commit f01c20b, implementing its design document)
> new option for tuning the behavior of the Go garbage collector by setting a soft memory limit on the total amount of memory that Go uses.
>
> This option comes in two flavors:
>
> - a new runtime/debug
function called SetMemoryLimit
and
> - a GOMEMLIMIT
environment variable.
>
> In sum, the runtime will try to maintain this memory limit by limiting the size of the heap, and by returning memory to the underlying platform more aggressively.
This includes with a mechanism to help mitigate garbage collection death spirals.
>
> Finally, by setting GOGC=off
, the Go runtime will always grow the heap to the full memory limit.
>
> This new option gives applications better control over their resource economy. It empowers users to:
>
> - Better utilize the memory that they already have,
> - Confidently decrease their memory limits, knowing Go will respect them,
> - Avoid unsupported forms of garbage collection tuning.
golang/go
issue 58106 clearly states:
> An alternative to increasing GOMEMLIMIT
is to switch to a GOGC
-based GC trigger once you get close to the limit.
This is effectively just a softer limit, but defined in terms of memory rather than CPU usage (which may be less noisy).
>
> You can calculate the "effective" GOGC
value at any given time like so:
>
> (/gc/heap/goal:bytes) / (/gc/heap/live:bytes + /gc/scan/stack:bytes + /gc/scan/globals:bytes) * 100 - 100
>
> and compare that against your target minimum GOGC
, say for example 10. If that value ever goes below 10, set SetGCPercent
to 10 and set GOMEMLIMIT
back to MaxInt64
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论