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
[RDY] Use jemalloc instead of libc allocator #2415
Conversation
/// free wrapper that returns delegates to the backing memory manager | ||
void xfree(void *ptr) | ||
{ | ||
free(ptr); |
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.
What's the purpose of xfree()
, if we redefine free()
? Is the plan to call je_*
explicitly from the xfoo
family, in the future?
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.
In this module, free
is only a placeholder for the actual free
implementation(which is je_free
when USE_JEMALLOC
is defined). We still need a fixed function address for the other modules to link against. Redefining free
as a macro globally is definitely not a good approach(we lose sanity when setting breakpoints, for example)
Is the plan to call je_* explicitly from the xfoo family, in the future?
No, but we could eventually use this as a slot for extra deallocation logic. For example, see how redis keeps track of how much memory is currently used in zmalloc.c.
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.
We still need a fixed function address for the other modules to link against. Redefining free as a macro globally is definitely not a good approach(we lose sanity when setting breakpoints, for example)
That makes perfect sense, thanks.
96152be
to
6988907
Compare
This causes a "read after free" error when kmp_free is replaced by `free`.
Klib pools were used to improve allocation efficiency for some small objects, but it is not a thread-safe approach. Thread safety in allocations will be required for implementing neovim#2371).
03a23fb
to
dbebead
Compare
@jszakmeister any idea what is causing the quickbuild failure? It seems to be bumping into jemalloc Makefile errors |
@@ -95,7 +95,7 @@ | |||
kmp_free(name, kl->mp, p); \ | |||
kmp_free(name, kl->mp, p); \ | |||
kmp_destroy(name, kl->mp); \ | |||
free(kl); \ | |||
xfree(kl); \ |
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.
alignment
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've been under the impression for a long time that GNU's malloc implementation is thread safe (when compiled with Some reading suggests that jemalloc is very good, even if thread safety isn't the main advantage, although I haven't seen a comparison against other allocation strategies yet. |
-DTARGET=jemalloc | ||
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/DownloadAndExtractFile.cmake | ||
BUILD_IN_SOURCE 1 | ||
CONFIGURE_COMMAND sh ${DEPS_BUILD_DIR}/src/jemalloc/autogen.sh && |
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.
This is failing on FreeBSD because the default BUILD_COMMAND invokes make, which is BSD make on FreeBSD. The install should build everything required, so all you need to do here is add BUILD_COMMAND ""
. HTH!
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.
👍 thanks
We already use wrappers for allocation, the new `xfree` function is the equivalent for deallocation and provides a way to fully replace the malloc implementation used by Neovim.
Jemalloc will be used if the cmake option `USE_JEMALLOC` is enabled(which is the default). To avoid trouble with clang's ASAN, it is disabled by default if the `SANITIZE` option is enabled. Since jemalloc has thread cache for small objects, it fills the gap created by removing klib memory pools. The `xstrdup` funciton(memory.c) had to be reimplemented on top of `xmalloc` to make it work with a custom allocator.
What I meant is that we relied on klib memory pools to optimize some event data allocations, and this would require synchronization for #2371 since the event producer and consumer would be running in different threads. The commit with replaces klib mempool by malloc/free takes care of the thread-safety problem, and the commit which adds jemalloc as a dependency fills the memory pool gap since it maintains thread-local cache for small allocations(it's also much simpler to leave caching to the allocator due to code simplification. |
free
wrapper to memory.c(xfree
). Required for customizing the memory allocator.I'm doing this more in preparation for #2371 which will require thread safety when dealing with memory allocated for queued events(memory pools would need to be explicitly synchronized, increasing complexity even more), but it should also improve overall allocation/deallocation efficiency due to reduced fragmentation and jemalloc's thread cache for small objects.
Could possibly fix #650, (cc @aktau)