mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-19 11:20:45 +00:00
cmd/utils: size Go memory limit from cgroup-aware limit
This commit is contained in:
parent
a61099fe36
commit
ca3a72e8c2
1 changed files with 16 additions and 25 deletions
|
|
@ -1771,32 +1771,23 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
||||||
// burned ~20% of CPU on `runtime.scanobject`/`gcDrain`/`findObject`
|
// burned ~20% of CPU on `runtime.scanobject`/`gcDrain`/`findObject`
|
||||||
// (confirmed by CPU profile of newPayload).
|
// (confirmed by CPU profile of newPayload).
|
||||||
//
|
//
|
||||||
// Modern Go (1.19+) supports SetMemoryLimit, which lets the runtime
|
// Modern Go (1.19+) supports SetMemoryLimit, which lets the runtime keep
|
||||||
// keep GOGC at the default 100 (fewer/larger collections) while still
|
// GOGC at the default 100 (fewer/larger collections) while still keeping
|
||||||
// guaranteeing memory stays below a soft cap. We size the cap so it's
|
// memory below a soft cap. We size the cap from the same cgroup-aware
|
||||||
// large enough that GOGC=100 governs steady-state behavior, but the
|
// limit used for the cache sanitizer above (total), so it's large enough
|
||||||
// limit kicks in if real memory pressure appears.
|
// that GOGC=100 governs steady state but the limit engages under real
|
||||||
cache := ctx.Int(CacheFlag.Name)
|
// memory pressure. When the effective limit can't be determined, leave
|
||||||
var memLimit int64
|
// Go's defaults untouched.
|
||||||
if mem, memErr := gopsutil.VirtualMemory(); memErr == nil && mem.Total > 0 {
|
if total > 0 {
|
||||||
// Leave half the host memory for the OS / page cache / other
|
cache := int64(ctx.Int(CacheFlag.Name)) * 1024 * 1024
|
||||||
// processes; cap the rest at roughly 4× the configured DB cache
|
// Target ~4× the cache so GOGC=100 governs steady state, but cap at
|
||||||
// to avoid runaway growth on machines with lots of RAM but a
|
// half of memory. The rest is for the OS, page cache, and off-heap
|
||||||
// modest --cache.
|
// caches like Pebble that SetMemoryLimit doesn't count.
|
||||||
halfHost := int64(mem.Total / 2)
|
memLimit := min(int64(total)/2, cache*4)
|
||||||
fourCache := int64(cache) * 4 * 1024 * 1024
|
log.Debug("Setting Go memory limit", "MB", memLimit/1024/1024, "source", source)
|
||||||
memLimit = min(halfHost, fourCache)
|
godebug.SetMemoryLimit(memLimit)
|
||||||
} else {
|
godebug.SetGCPercent(100)
|
||||||
// Fallback when the host's total memory isn't reportable.
|
|
||||||
memLimit = int64(cache) * 4 * 1024 * 1024
|
|
||||||
}
|
}
|
||||||
if memLimit < int64(cache)*1024*1024*2 {
|
|
||||||
// Always allow at least 2× the cache so the cache itself fits.
|
|
||||||
memLimit = int64(cache) * 1024 * 1024 * 2
|
|
||||||
}
|
|
||||||
log.Debug("Setting Go memory limit", "MB", memLimit/1024/1024)
|
|
||||||
godebug.SetMemoryLimit(memLimit)
|
|
||||||
godebug.SetGCPercent(100)
|
|
||||||
|
|
||||||
if ctx.IsSet(SyncTargetFlag.Name) {
|
if ctx.IsSet(SyncTargetFlag.Name) {
|
||||||
cfg.SyncMode = ethconfig.FullSync // dev sync target forces full sync
|
cfg.SyncMode = ethconfig.FullSync // dev sync target forces full sync
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue