Skip to content

Commit c1d5a01

Browse files
authored
core/state, tests: fix memory leak via fastcache (#28387)
This change fixes a memory leak, when running either state-tests or blockchain-tests, we allocate a `1MB` fastcache during snapshot generation. `fastcache` is a bit special, and requires a `Reset()` (it has it's own memory allocator). The `1MB` was hidden [here](https://github.com/ethereum/go-ethereum/blob/master/tests/state_test_util.go#L333) and [here](https://github.com/ethereum/go-ethereum/blob/master/tests/block_test_util.go#L146) respectively.
1 parent cd29535 commit c1d5a01

File tree

6 files changed

+26
-1
lines changed

6 files changed

+26
-1
lines changed

appveyor.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,4 @@ for:
5454
- go run build/ci.go archive -arch %GETH_ARCH% -type zip -signer WINDOWS_SIGNING_KEY -upload gethstore/builds
5555
- go run build/ci.go nsis -arch %GETH_ARCH% -signer WINDOWS_SIGNING_KEY -upload gethstore/builds
5656
test_script:
57-
- go run build/ci.go test -dlgo -arch %GETH_ARCH% -cc %GETH_CC%
57+
- go run build/ci.go test -dlgo -arch %GETH_ARCH% -cc %GETH_CC% -short

build/ci.go

+4
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ func doTest(cmdline []string) {
285285
coverage = flag.Bool("coverage", false, "Whether to record code coverage")
286286
verbose = flag.Bool("v", false, "Whether to log verbosely")
287287
race = flag.Bool("race", false, "Execute the race detector")
288+
short = flag.Bool("short", false, "Pass the 'short'-flag to go test")
288289
cachedir = flag.String("cachedir", "./build/cache", "directory for caching downloads")
289290
)
290291
flag.CommandLine.Parse(cmdline)
@@ -318,6 +319,9 @@ func doTest(cmdline []string) {
318319
if *race {
319320
gotest.Args = append(gotest.Args, "-race")
320321
}
322+
if *short {
323+
gotest.Args = append(gotest.Args, "-short")
324+
}
321325

322326
packages := []string{"./..."}
323327
if len(flag.CommandLine.Args()) > 0 {

core/blockchain.go

+1
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,7 @@ func (bc *BlockChain) Stop() {
989989
if snapBase, err = bc.snaps.Journal(bc.CurrentBlock().Root); err != nil {
990990
log.Error("Failed to journal state snapshot", "err", err)
991991
}
992+
bc.snaps.Release()
992993
}
993994
if bc.triedb.Scheme() == rawdb.PathScheme {
994995
// Ensure that the in-memory trie nodes are journaled to disk properly.

core/state/snapshot/disklayer.go

+10
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,16 @@ type diskLayer struct {
4545
lock sync.RWMutex
4646
}
4747

48+
// Release releases underlying resources; specifically the fastcache requires
49+
// Reset() in order to not leak memory.
50+
// OBS: It does not invoke Close on the diskdb
51+
func (dl *diskLayer) Release() error {
52+
if dl.cache != nil {
53+
dl.cache.Reset()
54+
}
55+
return nil
56+
}
57+
4858
// Root returns root hash for which this snapshot was made.
4959
func (dl *diskLayer) Root() common.Hash {
5060
return dl.root

core/state/snapshot/snapshot.go

+7
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,13 @@ func diffToDisk(bottom *diffLayer) *diskLayer {
656656
return res
657657
}
658658

659+
// Release releases resources
660+
func (t *Tree) Release() {
661+
if dl := t.disklayer(); dl != nil {
662+
dl.Release()
663+
}
664+
}
665+
659666
// Journal commits an entire diff hierarchy to disk into a single journal entry.
660667
// This is meant to be used during shutdown to persist the snapshot without
661668
// flattening everything down (bad for reorgs).

tests/state_test_util.go

+3
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config, snapshotter bo
200200
if triedb != nil {
201201
triedb.Close()
202202
}
203+
if snaps != nil {
204+
snaps.Release()
205+
}
203206
}()
204207
checkedErr := t.checkError(subtest, err)
205208
if checkedErr != nil {

0 commit comments

Comments
 (0)