package system import ( "os" "github.com/dustin/go-humanize" "github.com/elastic/gosigar" logging "github.com/ipfs/go-log/v2" ) var ( logSystem = logging.Logger("system") ) // EnvMaximumHeap is name of the environment variable with which the user can // specify a maximum heap size to abide by. The value of the env variable should // be in bytes, or in SI bytes (e.g. 32GiB). const EnvMaximumHeap = "LOTUS_MAX_HEAP" // MemoryConstraints represents resource constraints that Lotus and the go // runtime should abide by. It is a singleton object that's populated on // initialization, and can be used by components for size calculations // (e.g. caches). type MemoryConstraints struct { // MaxHeapMem is the maximum heap memory that has been set by the user // through the LOTUS_MAX_HEAP env variable. If zero, there is no max heap // limit set. MaxHeapMem uint64 // TotalSystemMem is the total system memory as reported by go-sigar. If // zero, it was impossible to determine the total system memory. TotalSystemMem uint64 // EffectiveMemLimit is the memory limit in effect, in bytes. // // In order of precedence: // 1. MaxHeapMem if non-zero. // 2. TotalSystemMem if non-zero. // 3. Zero (no known limit). EffectiveMemLimit uint64 } // GetMemoryConstraints returns the memory constraints for this process. func GetMemoryConstraints() (ret MemoryConstraints) { var mem gosigar.Mem if err := mem.Get(); err != nil { logSystem.Warnf("failed to acquire total system memory: %s", err) } else { ret.TotalSystemMem = mem.Total ret.EffectiveMemLimit = mem.Total } if v := os.Getenv(EnvMaximumHeap); v != "" { bytes, err := humanize.ParseBytes(v) if err != nil { logSystem.Warnf("failed to parse %s env variable with value %s: %s; ignoring max heap limit", EnvMaximumHeap, v, err) } else { ret.MaxHeapMem = bytes ret.EffectiveMemLimit = bytes } } return ret }