2020-08-11 19:54:13 +00:00
|
|
|
package cgroup
|
|
|
|
|
2021-02-08 13:46:22 +00:00
|
|
|
import (
|
2021-07-05 09:31:26 +00:00
|
|
|
"os"
|
|
|
|
"runtime/debug"
|
2021-02-08 13:46:22 +00:00
|
|
|
"strconv"
|
|
|
|
)
|
|
|
|
|
2021-07-05 09:31:26 +00:00
|
|
|
// GetGOGC returns GOGC value for the currently running process.
|
|
|
|
//
|
|
|
|
// See https://golang.org/pkg/runtime/#hdr-Environment_Variables for more details about GOGC
|
|
|
|
func GetGOGC() int {
|
|
|
|
return gogc
|
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
initGOGC()
|
|
|
|
}
|
|
|
|
|
|
|
|
func initGOGC() {
|
|
|
|
if v := os.Getenv("GOGC"); v != "" {
|
2022-04-06 10:32:01 +00:00
|
|
|
n, err := strconv.ParseFloat(v, 64)
|
2021-07-05 09:31:26 +00:00
|
|
|
if err != nil {
|
|
|
|
n = 100
|
|
|
|
}
|
2022-04-06 10:32:01 +00:00
|
|
|
gogc = int(n)
|
2021-07-05 09:31:26 +00:00
|
|
|
} else {
|
2022-04-06 10:32:01 +00:00
|
|
|
// Use lower GOGC if it isn't set yet.
|
|
|
|
// This should reduce memory usage for typical workloads for VictoriaMetrics components
|
|
|
|
// at the cost of increased CPU usage.
|
|
|
|
// It is recommended increasing GOGC if go_memstats_gc_cpu_fraction exceeds 0.05 for extended periods of time.
|
|
|
|
gogc = 30
|
2021-07-05 09:31:26 +00:00
|
|
|
debug.SetGCPercent(gogc)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-20 05:38:58 +00:00
|
|
|
// SetGOGC sets GOGC to the given percent
|
|
|
|
func SetGOGC(percent int) {
|
|
|
|
if percent <= 0 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if percent > 100 {
|
|
|
|
percent = 100
|
|
|
|
}
|
|
|
|
gogc = percent
|
|
|
|
debug.SetGCPercent(gogc)
|
|
|
|
}
|
|
|
|
|
2021-07-05 09:31:26 +00:00
|
|
|
var gogc int
|
|
|
|
|
2020-08-11 19:54:13 +00:00
|
|
|
// GetMemoryLimit returns cgroup memory limit
|
|
|
|
func GetMemoryLimit() int64 {
|
|
|
|
// Try determining the amount of memory inside docker container.
|
|
|
|
// See https://stackoverflow.com/questions/42187085/check-mem-limit-within-a-docker-container
|
|
|
|
//
|
|
|
|
// Read memory limit according to https://unix.stackexchange.com/questions/242718/how-to-find-out-how-much-memory-lxc-container-is-allowed-to-consume
|
|
|
|
// This should properly determine the limit inside lxc container.
|
|
|
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/84
|
2021-02-08 13:49:02 +00:00
|
|
|
n, err := getMemStat("memory.limit_in_bytes")
|
2021-05-13 06:02:13 +00:00
|
|
|
if err == nil {
|
|
|
|
return n
|
|
|
|
}
|
2021-05-13 06:26:20 +00:00
|
|
|
n, err = getMemStatV2("memory.max")
|
2020-08-11 19:54:13 +00:00
|
|
|
if err != nil {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
return n
|
|
|
|
}
|
2020-09-03 21:04:08 +00:00
|
|
|
|
2021-05-13 06:26:20 +00:00
|
|
|
func getMemStatV2(statName string) (int64, error) {
|
|
|
|
// See https: //www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html#memory-interface-files
|
|
|
|
return getStatGeneric(statName, "/sys/fs/cgroup", "/proc/self/cgroup", "")
|
2021-05-13 06:02:13 +00:00
|
|
|
}
|
|
|
|
|
2021-02-08 13:49:02 +00:00
|
|
|
func getMemStat(statName string) (int64, error) {
|
|
|
|
return getStatGeneric(statName, "/sys/fs/cgroup/memory", "/proc/self/cgroup", "memory")
|
2021-02-08 13:46:22 +00:00
|
|
|
}
|
|
|
|
|
2020-09-03 21:04:08 +00:00
|
|
|
// GetHierarchicalMemoryLimit returns hierarchical memory limit
|
2021-02-08 13:46:22 +00:00
|
|
|
// https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt
|
2020-09-03 21:04:08 +00:00
|
|
|
func GetHierarchicalMemoryLimit() int64 {
|
|
|
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/699
|
2021-02-08 13:46:22 +00:00
|
|
|
n, err := getHierarchicalMemoryLimit("/sys/fs/cgroup/memory", "/proc/self/cgroup")
|
2020-09-03 21:04:08 +00:00
|
|
|
if err != nil {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
return n
|
|
|
|
}
|
2021-02-08 13:46:22 +00:00
|
|
|
|
2021-02-08 13:49:02 +00:00
|
|
|
func getHierarchicalMemoryLimit(sysfsPrefix, cgroupPath string) (int64, error) {
|
|
|
|
data, err := getFileContents("memory.stat", sysfsPrefix, cgroupPath, "memory")
|
2021-02-08 13:46:22 +00:00
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
2021-02-08 13:49:02 +00:00
|
|
|
memStat, err := grepFirstMatch(data, "hierarchical_memory_limit", 1, " ")
|
2021-02-08 13:46:22 +00:00
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
return strconv.ParseInt(memStat, 10, 64)
|
|
|
|
}
|