From 59a6d3555a18ad9f3915960f07cf8e54c96cf6c2 Mon Sep 17 00:00:00 2001 From: j2rong4cn Date: Wed, 27 May 2026 22:10:12 +0800 Subject: [PATCH] fix(cache,mem): replace finalizers with runtime.AddCleanup Replaces ad-hoc runtime.SetFinalizer usage with runtime.AddCleanup and explicit cleanup fields to register close/free actions. Ensures cleanup.Stop is invoked on explicit Close/Free, improving deterministic resource management and avoiding reliance on GC finalizers that can be delayed or racy. Removes previous finalizer setup and wires cleanup registration for backing stores and guarded memory. --- internal/hybrid_cache/hybrid_cache.go | 11 +++++------ internal/mem/utils.go | 14 ++++++++++---- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/internal/hybrid_cache/hybrid_cache.go b/internal/hybrid_cache/hybrid_cache.go index d80f768f1..c69147937 100644 --- a/internal/hybrid_cache/hybrid_cache.go +++ b/internal/hybrid_cache/hybrid_cache.go @@ -18,6 +18,7 @@ type HybridCache struct { memoryOffset uint64 backingStore BackingStore backingOffset uint64 + cleanup runtime.Cleanup } // HybridCache本身是一个大的Block,支持分块成多个小的Block @@ -99,11 +100,15 @@ func (hc *HybridCache) initFileCache() error { if err != nil { return err } + hc.cleanup = runtime.AddCleanup(hc, func(file BackingStore) { + _ = file.Close() + }, file) hc.backingStore = file return nil } func (hc *HybridCache) Close() error { + hc.cleanup.Stop() var err error if hc.memoryStore != nil { err = hc.memoryStore.Free() @@ -228,12 +233,6 @@ func NewHybridCache(blockSize, maxMemorySize uint64) (hc *HybridCache, err error return nil, errors.Join(err, err2) } } - runtime.SetFinalizer(hc, func(hc *HybridCache) { - if hc.backingStore != nil { - _ = hc.backingStore.Close() - hc.backingStore = nil - } - }) return hc, nil } diff --git a/internal/mem/utils.go b/internal/mem/utils.go index 21944066d..b0a46d731 100644 --- a/internal/mem/utils.go +++ b/internal/mem/utils.go @@ -58,15 +58,16 @@ func NewGuardedMemory(cap, max uint64) (m LinearMemory, err error) { if s, ok := m.(interface{ SetGrowCheck(GrowCheck) }); ok { s.SetGrowCheck(MemoryGrowCheck) } - gm := &guardedMemory{m} - runtime.SetFinalizer(gm, func(gm *guardedMemory) { - gm.Free() - }) + gm := &guardedMemory{LinearMemory: m} + gm.cleanup = runtime.AddCleanup(gm, func(m LinearMemory) { + m.Free() + }, m) return gm, nil } type guardedMemory struct { LinearMemory + cleanup runtime.Cleanup } func (s *guardedMemory) Reallocate(size uint64) (all []byte, err error) { @@ -77,3 +78,8 @@ func (s *guardedMemory) Reallocate(size uint64) (all []byte, err error) { }() return s.LinearMemory.Reallocate(size) } + +func (s *guardedMemory) Free() error { + s.cleanup.Stop() + return s.LinearMemory.Free() +}