diff --git a/core/blockchain.go b/core/blockchain.go index baf2f9f82f..fc5c249ce2 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -989,6 +989,7 @@ func (bc *BlockChain) Stop() { if snapBase, err = bc.snaps.Journal(bc.CurrentBlock().Root); err != nil { log.Error("Failed to journal state snapshot", "err", err) } + bc.snaps.Release() } if bc.triedb.Scheme() == rawdb.PathScheme { // Ensure that the in-memory trie nodes are journaled to disk properly. diff --git a/core/state/snapshot/disklayer.go b/core/state/snapshot/disklayer.go index 513f0f5aba..98337bea9f 100644 --- a/core/state/snapshot/disklayer.go +++ b/core/state/snapshot/disklayer.go @@ -45,6 +45,17 @@ type diskLayer struct { lock sync.RWMutex } +// Release releases underlying resources; specifically the fastcache requires +// Reset() in order to not leak memory. +// OBS: It does not invoke Close on the diskdb +func (dl *diskLayer) Release() error { + if dl.cache != nil { + dl.cache.Reset() + dl.cache = nil + } + return nil +} + // Root returns root hash for which this snapshot was made. func (dl *diskLayer) Root() common.Hash { return dl.root diff --git a/core/state/snapshot/snapshot.go b/core/state/snapshot/snapshot.go index e30a0005cc..6389842382 100644 --- a/core/state/snapshot/snapshot.go +++ b/core/state/snapshot/snapshot.go @@ -656,6 +656,13 @@ func diffToDisk(bottom *diffLayer) *diskLayer { return res } +// Release releases resources +func (t *Tree) Release() { + if dl := t.disklayer(); dl != nil { + dl.Release() + } +} + // Journal commits an entire diff hierarchy to disk into a single journal entry. // This is meant to be used during shutdown to persist the snapshot without // flattening everything down (bad for reorgs). diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 8c255c1b5b..745a3c6b28 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -200,6 +200,9 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config, snapshotter bo if triedb != nil { triedb.Close() } + if snaps != nil { + snaps.Release() + } }() checkedErr := t.checkError(subtest, err) if checkedErr != nil {