lib/mergeset: switch from sync.Pool to a channel for a pool for inmemoryBlock structs

This should reduce memory usage for the pool on systems with big number of CPU cores.

The sync.Pool maintains per-CPU pools, so the total number of objects in the pool
is proportional to the number of available CPU cores. The channel limits the number
of pooled objects by its own capacity. This means smaller number of pooled objects on average.
This commit is contained in:
Aliaksandr Valialkin 2021-06-29 19:49:05 +03:00
parent 2edfea8c36
commit b7c0b3dde3

View file

@ -10,6 +10,7 @@ import (
"unsafe" "unsafe"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil" "github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/cgroup"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/encoding" "github.com/VictoriaMetrics/VictoriaMetrics/lib/encoding"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger" "github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
) )
@ -541,16 +542,24 @@ func putLensBuffer(lb *lensBuffer) {
} }
func getInmemoryBlock() *inmemoryBlock { func getInmemoryBlock() *inmemoryBlock {
v := ibPool.Get() select {
if v == nil { case ib := <-ibPoolCh:
return ib
default:
return &inmemoryBlock{} return &inmemoryBlock{}
} }
return v.(*inmemoryBlock)
} }
func putInmemoryBlock(ib *inmemoryBlock) { func putInmemoryBlock(ib *inmemoryBlock) {
ib.Reset() ib.Reset()
ibPool.Put(ib) select {
case ibPoolCh <- ib:
default:
// drop ib in order to reduce memory usage on systems with big number of CPU cores
}
} }
var ibPool sync.Pool // Every inmemoryBlock struct occupies at least 64KB of memory, e.g. quite big amounts of memory.
// Use a chan instead of sync.Pool in order to reduce memory usage on systems
// with big number of CPU cores.
var ibPoolCh = make(chan *inmemoryBlock, cgroup.AvailableCPUs())