From b7c0b3dde360e63e81814cd7a5630f8aa27c941c Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Tue, 29 Jun 2021 19:49:05 +0300 Subject: [PATCH] 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. --- lib/mergeset/encoding.go | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/mergeset/encoding.go b/lib/mergeset/encoding.go index 8cb57082c..dce5ae034 100644 --- a/lib/mergeset/encoding.go +++ b/lib/mergeset/encoding.go @@ -10,6 +10,7 @@ import ( "unsafe" "github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil" + "github.com/VictoriaMetrics/VictoriaMetrics/lib/cgroup" "github.com/VictoriaMetrics/VictoriaMetrics/lib/encoding" "github.com/VictoriaMetrics/VictoriaMetrics/lib/logger" ) @@ -541,16 +542,24 @@ func putLensBuffer(lb *lensBuffer) { } func getInmemoryBlock() *inmemoryBlock { - v := ibPool.Get() - if v == nil { + select { + case ib := <-ibPoolCh: + return ib + default: return &inmemoryBlock{} } - return v.(*inmemoryBlock) } func putInmemoryBlock(ib *inmemoryBlock) { 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())