@@ -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
@@ -1147,6 +1150,26 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
11471150 setTxPool (ctx , & cfg .TxPool )
11481151 setEthash (ctx , cfg )
11491152
1153+ // Cap the cache allowance and tune the garbage collector
1154+ mem , err := gopsutil .VirtualMemory ()
1155+ if err == nil {
1156+ if 32 << (^ uintptr (0 )>> 63 ) == 32 && mem .Total > 2 * 1024 * 1024 * 1024 {
1157+ log .Warn ("Lowering memory allowance on 32bit arch" , "available" , mem .Total / 1024 / 1024 , "addressable" , 2 * 1024 )
1158+ mem .Total = 2 * 1024 * 1024 * 1024
1159+ }
1160+ allowance := int (mem .Total / 1024 / 1024 / 3 )
1161+ if cache := ctx .Int (CacheFlag .Name ); cache > allowance {
1162+ log .Warn ("Sanitizing cache to Go's GC limits" , "provided" , cache , "updated" , allowance )
1163+ ctx .Set (CacheFlag .Name , strconv .Itoa (allowance ))
1164+ }
1165+ }
1166+ // Ensure Go's GC ignores the database cache for trigger percentage
1167+ cache := ctx .Int (CacheFlag .Name )
1168+ gogc := math .Max (20 , math .Min (100 , 100 / (float64 (cache )/ 1024 )))
1169+
1170+ log .Debug ("Sanitizing Go's GC trigger" , "percent" , int (gogc ))
1171+ godebug .SetGCPercent (int (gogc ))
1172+
11501173 switch {
11511174 case ctx .GlobalIsSet (SyncModeFlag .Name ):
11521175 cfg .SyncMode = * GlobalTextMarshaler (ctx , SyncModeFlag .Name ).(* downloader.SyncMode )
0 commit comments