64 lines
1.4 KiB
Go
64 lines
1.4 KiB
Go
package analyze
|
|
|
|
import (
|
|
"runtime"
|
|
"runtime/debug"
|
|
"time"
|
|
|
|
"github.com/pbnjay/memory"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// set GC percentage according to memory usage and system free memory
|
|
func manageMemoryUsage(c <-chan struct{}) {
|
|
disabledGC := true
|
|
|
|
for {
|
|
select {
|
|
case <-c:
|
|
return
|
|
default:
|
|
}
|
|
|
|
time.Sleep(time.Second)
|
|
|
|
rebalanceGC(&disabledGC)
|
|
}
|
|
}
|
|
|
|
/*
|
|
Try to balance performance and memory consumption.
|
|
|
|
When less memory is used by gdu than the total free memory of the host,
|
|
Garbage Collection is disabled during the analysis phase at all.
|
|
|
|
Otherwise GC is enabled.
|
|
The more memory is used and the less memory is free,
|
|
the more often will the GC happen.
|
|
*/
|
|
func rebalanceGC(disabledGC *bool) {
|
|
memStats := runtime.MemStats{}
|
|
runtime.ReadMemStats(&memStats)
|
|
free := memory.FreeMemory()
|
|
|
|
// we use less memory than is free, disable GC
|
|
if memStats.Alloc < free {
|
|
if !*disabledGC {
|
|
log.Printf(
|
|
"disabling GC, alloc: %d, free: %d", memStats.Alloc, free,
|
|
)
|
|
debug.SetGCPercent(-1)
|
|
*disabledGC = true
|
|
}
|
|
} else {
|
|
// the more memory we use and the less memory is free, the more aggressive the GC will be
|
|
gcPercent := int(100 / float64(memStats.Alloc) * float64(free))
|
|
log.Printf(
|
|
"setting GC percent to %d, alloc: %d, free: %d",
|
|
gcPercent, memStats.Alloc, free,
|
|
)
|
|
debug.SetGCPercent(gcPercent)
|
|
*disabledGC = false
|
|
}
|
|
}
|