Skip to content

Commit 959e53c

Browse files
committed
fastcache.go: re-create the bucket.m map inside cleanLocked() in order to reduce map fragmentation
Hopefully, this may help reducing memory usage and GC pressure for long-running processes, which use fastcache. See VictoriaMetrics/VictoriaMetrics#5379
1 parent 80e8ba2 commit 959e53c

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

fastcache.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,13 +272,27 @@ func (b *bucket) cleanLocked() {
272272
bGen := b.gen & ((1 << genSizeBits) - 1)
273273
bIdx := b.idx
274274
bm := b.m
275-
for k, v := range bm {
275+
newItems := 0
276+
for _, v := range bm {
276277
gen := v >> bucketSizeBits
277278
idx := v & ((1 << bucketSizeBits) - 1)
278279
if (gen+1 == bGen || gen == maxGen && bGen == 1) && idx >= bIdx || gen == bGen && idx < bIdx {
279-
continue
280+
newItems++
280281
}
281-
delete(bm, k)
282+
}
283+
if newItems < len(bm) {
284+
// Re-create b.m with valid items, which weren't expired yet instead of deleting expired items from b.m.
285+
// This should reduce memory fragmentation and the number Go objects behind b.m.
286+
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5379
287+
bmNew := make(map[uint64]uint64, newItems)
288+
for k, v := range bm {
289+
gen := v >> bucketSizeBits
290+
idx := v & ((1 << bucketSizeBits) - 1)
291+
if (gen+1 == bGen || gen == maxGen && bGen == 1) && idx >= bIdx || gen == bGen && idx < bIdx {
292+
bmNew[k] = v
293+
}
294+
}
295+
b.m = bmNew
282296
}
283297
}
284298

0 commit comments

Comments
 (0)