mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 13:21:37 +00:00
cmd/geth: add --gcpercent flag for GC tuning
Add a --gcpercent flag that overrides the Go runtime's GOGC value at startup. When not set, the existing cache-based auto-tuning is used. CPU profiling of the binary trie (EIP-7864) shows 44% of CPU time spent in garbage collection due to the large live object graph (~25K InternalNodes). Reducing GC frequency via higher GOGC significantly improves read-heavy workloads at the cost of higher memory usage. This flag lets operators tune based on their workload: - Validators (write-heavy): default or --gcpercent=100 - RPC nodes (read-heavy): --gcpercent=200 or higher
This commit is contained in:
parent
98b13f342f
commit
2c4d669f5d
2 changed files with 20 additions and 6 deletions
|
|
@ -108,6 +108,7 @@ var (
|
|||
utils.CacheNoPrefetchFlag,
|
||||
utils.CachePreimagesFlag,
|
||||
utils.CacheLogSizeFlag,
|
||||
utils.GCPercentFlag,
|
||||
utils.FDLimitFlag,
|
||||
utils.CryptoKZGFlag,
|
||||
utils.ListenPortFlag,
|
||||
|
|
|
|||
|
|
@ -528,6 +528,12 @@ var (
|
|||
Category: flags.PerfCategory,
|
||||
Value: ethconfig.Defaults.FilterLogCacheSize,
|
||||
}
|
||||
GCPercentFlag = &cli.IntFlag{
|
||||
Name: "gcpercent",
|
||||
Usage: "Set garbage collection target percentage (GOGC). Higher values reduce GC frequency, improving read throughput at the cost of memory. 0 means use the cache-based default",
|
||||
Value: 0,
|
||||
Category: flags.PerfCategory,
|
||||
}
|
||||
FDLimitFlag = &cli.IntFlag{
|
||||
Name: "fdlimit",
|
||||
Usage: "Raise the open file descriptor resource limit (default = system fd limit)",
|
||||
|
|
@ -1752,12 +1758,19 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
|||
ctx.Set(CacheFlag.Name, strconv.Itoa(allowance))
|
||||
}
|
||||
}
|
||||
// Ensure Go's GC ignores the database cache for trigger percentage
|
||||
cache := ctx.Int(CacheFlag.Name)
|
||||
gogc := max(20, min(100, 100/(float64(cache)/1024)))
|
||||
|
||||
log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc))
|
||||
godebug.SetGCPercent(int(gogc))
|
||||
// Set Go's GC target percentage. If --gcpercent is explicitly set, use
|
||||
// that value directly. Otherwise, compute a default based on cache size
|
||||
// to prevent the GC from treating the database cache as free memory.
|
||||
if ctx.IsSet(GCPercentFlag.Name) {
|
||||
gogc := ctx.Int(GCPercentFlag.Name)
|
||||
log.Info("Set GC target percentage", "GOGC", gogc)
|
||||
godebug.SetGCPercent(gogc)
|
||||
} else {
|
||||
cache := ctx.Int(CacheFlag.Name)
|
||||
gogc := max(20, min(100, 100/(float64(cache)/1024)))
|
||||
log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc))
|
||||
godebug.SetGCPercent(int(gogc))
|
||||
}
|
||||
|
||||
if ctx.IsSet(SyncTargetFlag.Name) {
|
||||
cfg.SyncMode = ethconfig.FullSync // dev sync target forces full sync
|
||||
|
|
|
|||
Loading…
Reference in a new issue