@@ -20,10 +20,12 @@ package utils
2020import (
2121 "crypto/ecdsa"
2222 "fmt"
23+ "math"
2324 "math/big"
2425 "os"
2526 "path/filepath"
2627 "runtime"
28+ godebug "runtime/debug"
2729 "strconv"
2830 "strings"
2931
@@ -53,6 +55,7 @@ import (
5355 "github.com/XinFinOrg/XDPoSChain/p2p/netutil"
5456 "github.com/XinFinOrg/XDPoSChain/params"
5557 whisper "github.com/XinFinOrg/XDPoSChain/whisper/whisperv6"
58+ gopsutil "github.com/shirou/gopsutil/mem"
5659 "gopkg.in/urfave/cli.v1"
5760)
5861
@@ -1175,6 +1178,26 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
11751178 setTxPool (ctx , & cfg .TxPool )
11761179 setEthash (ctx , cfg )
11771180
1181+ // Cap the cache allowance and tune the garbage collector
1182+ mem , err := gopsutil .VirtualMemory ()
1183+ if err == nil {
1184+ if 32 << (^ uintptr (0 )>> 63 ) == 32 && mem .Total > 2 * 1024 * 1024 * 1024 {
1185+ log .Warn ("Lowering memory allowance on 32bit arch" , "available" , mem .Total / 1024 / 1024 , "addressable" , 2 * 1024 )
1186+ mem .Total = 2 * 1024 * 1024 * 1024
1187+ }
1188+ allowance := int (mem .Total / 1024 / 1024 / 3 )
1189+ if cache := ctx .Int (CacheFlag .Name ); cache > allowance {
1190+ log .Warn ("Sanitizing cache to Go's GC limits" , "provided" , cache , "updated" , allowance )
1191+ ctx .Set (CacheFlag .Name , strconv .Itoa (allowance ))
1192+ }
1193+ }
1194+ // Ensure Go's GC ignores the database cache for trigger percentage
1195+ cache := ctx .Int (CacheFlag .Name )
1196+ gogc := math .Max (20 , math .Min (100 , 100 / (float64 (cache )/ 1024 )))
1197+
1198+ log .Debug ("Sanitizing Go's GC trigger" , "percent" , int (gogc ))
1199+ godebug .SetGCPercent (int (gogc ))
1200+
11781201 switch {
11791202 case ctx .GlobalIsSet (SyncModeFlag .Name ):
11801203 cfg .SyncMode = * GlobalTextMarshaler (ctx , SyncModeFlag .Name ).(* downloader.SyncMode )
0 commit comments