diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index c178bee59f..a8b5514561 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -20,10 +20,12 @@ package utils import ( "crypto/ecdsa" "fmt" + "math" "math/big" "os" "path/filepath" "runtime" + godebug "runtime/debug" "strconv" "strings" @@ -53,6 +55,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/p2p/netutil" "github.com/XinFinOrg/XDPoSChain/params" whisper "github.com/XinFinOrg/XDPoSChain/whisper/whisperv6" + gopsutil "github.com/shirou/gopsutil/mem" "gopkg.in/urfave/cli.v1" ) @@ -1175,6 +1178,26 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { setTxPool(ctx, &cfg.TxPool) setEthash(ctx, cfg) + // Cap the cache allowance and tune the garbage collector + mem, err := gopsutil.VirtualMemory() + if err == nil { + if 32<<(^uintptr(0)>>63) == 32 && mem.Total > 2*1024*1024*1024 { + log.Warn("Lowering memory allowance on 32bit arch", "available", mem.Total/1024/1024, "addressable", 2*1024) + mem.Total = 2 * 1024 * 1024 * 1024 + } + allowance := int(mem.Total / 1024 / 1024 / 3) + if cache := ctx.Int(CacheFlag.Name); cache > allowance { + log.Warn("Sanitizing cache to Go's GC limits", "provided", cache, "updated", allowance) + ctx.Set(CacheFlag.Name, strconv.Itoa(allowance)) + } + } + // Ensure Go's GC ignores the database cache for trigger percentage + cache := ctx.Int(CacheFlag.Name) + gogc := math.Max(20, math.Min(100, 100/(float64(cache)/1024))) + + log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc)) + godebug.SetGCPercent(int(gogc)) + switch { case ctx.GlobalIsSet(SyncModeFlag.Name): cfg.SyncMode = *GlobalTextMarshaler(ctx, SyncModeFlag.Name).(*downloader.SyncMode)