@@ -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
@@ -1174,6 +1177,26 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
11741177 setTxPool (ctx , & cfg .TxPool )
11751178 setEthash (ctx , cfg )
11761179
1180+ // Cap the cache allowance and tune the garbage collector
1181+ mem , err := gopsutil .VirtualMemory ()
1182+ if err == nil {
1183+ if 32 << (^ uintptr (0 )>> 63 ) == 32 && mem .Total > 2 * 1024 * 1024 * 1024 {
1184+ log .Warn ("Lowering memory allowance on 32bit arch" , "available" , mem .Total / 1024 / 1024 , "addressable" , 2 * 1024 )
1185+ mem .Total = 2 * 1024 * 1024 * 1024
1186+ }
1187+ allowance := int (mem .Total / 1024 / 1024 / 3 )
1188+ if cache := ctx .Int (CacheFlag .Name ); cache > allowance {
1189+ log .Warn ("Sanitizing cache to Go's GC limits" , "provided" , cache , "updated" , allowance )
1190+ ctx .Set (CacheFlag .Name , strconv .Itoa (allowance ))
1191+ }
1192+ }
1193+ // Ensure Go's GC ignores the database cache for trigger percentage
1194+ cache := ctx .Int (CacheFlag .Name )
1195+ gogc := math .Max (20 , math .Min (100 , 100 / (float64 (cache )/ 1024 )))
1196+
1197+ log .Debug ("Sanitizing Go's GC trigger" , "percent" , int (gogc ))
1198+ godebug .SetGCPercent (int (gogc ))
1199+
11771200 switch {
11781201 case ctx .GlobalIsSet (SyncModeFlag .Name ):
11791202 cfg .SyncMode = * GlobalTextMarshaler (ctx , SyncModeFlag .Name ).(* downloader.SyncMode )
0 commit comments