-
Notifications
You must be signed in to change notification settings - Fork 20.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
core/state, trie: fix memleak from fastcache #26071
Conversation
这是来自QQ邮箱的假期自动回复邮件。
您好,我最近正在休假中,无法亲自回复您的邮件。我将在假期结束后,尽快给您回复。
|
db: trie.NewDatabaseWithConfig(db, config), | ||
disk: db, | ||
codeSizeCache: csc, | ||
codeCache: fastcache.New(codeCacheSize), | ||
} | ||
runtime.SetFinalizer(cdb, (*cachingDB).finalizer) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like it's unnecessary to use fastcache here as the codeCache. fastCache is mostly for caching large amount of data for GC-friendly purpose. Obviously not the case here.
Another option would be to maintain an in-house fastcache fork, which would have a finalizer on caches that frees them like you'd expect from Go being a garbage collected language. The upstream fastcache library is also unmaintained, e.g. VictoriaMetrics/fastcache#66 . I'd be happy to implement this but I want to make sure it makes sense first. |
Using finalizers is the wrong approach really, both in the library and in this code. The docs clearly state that Reset needs to be called. One option is to use the API correctly here, another is to use a caching library that does not need an explicit close mechanism. |
I looked into doing that -- calling I think we might be better off using a caching library which does not have it's own allocator. The code cache is a 64 MB cache (pretty tiny), we don't need a cache-on-steroids library for that little thing, |
@holiman totally agree |
To follow up The fact that |
Thanks for bringing this to our attention, but we will not merge this PR, since we don't think the solution is the best. We'll probably use #26092 to fix the problem instead. |
Fastcache uses memory allocated by mmap, which is not garbage collected.
Data filled in the codeCache is therefore leaked when the stateDatabase is discarded (e.g. in StateAtBlock).
Same goes for cleans fastcache when used in the TrieDB.
Reset() doesn't unmap memory from the OS, but it does move all chunks to fastcache's global free chunk list, allowing it to be reused by later instances.
Fastcache is also used by the snapshot. I did not add Reset to those instances to minimize diff and because the snapshot is not regularly discarded. I can add cleaning that up as well if you wish.