diff --git a/README.md b/README.md index b958a90b61..99e4f6846f 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,25 @@ If you want to see a more verbose output, use the following: % make V=1 +Using mimalloc with Valkey +------------- + +[mimalloc](https://github.com/microsoft/mimalloc) is an advanced memory allocator that can improve the performance of applications. You can optionally build Valkey using mimalloc by following these steps: + +Before building Valkey with mimalloc, you need to install mimalloc on your system. + + % git clone https://github.com/microsoft/mimalloc.git + % mkdir -p mimalloc/out/release + % cd mimalloc/out/release + % cmake ../.. -DMI_INSTALL_TOPLEVEL=ON + % sudo make install + +This will install mimalloc libraries and headers in /usr/local/lib and /usr/local/include. + +Build Valkey with mimalloc: + + % make MALLOC=mimalloc + Running Valkey ------------- diff --git a/src/Makefile b/src/Makefile index 833349839f..5b6632aee6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -98,6 +98,10 @@ ifeq ($(USE_JEMALLOC),no) MALLOC=libc endif +ifeq ($(USE_MIMALLOC),yes) + MALLOC=mimalloc +endif + ifdef SANITIZER ifeq ($(SANITIZER),address) MALLOC=libc @@ -288,6 +292,13 @@ ifeq ($(MALLOC),jemalloc) FINAL_LIBS := ../deps/jemalloc/lib/libjemalloc.a $(FINAL_LIBS) endif +ifeq ($(MALLOC),mimalloc) + FINAL_CFLAGS+= -DUSE_MIMALLOC -I/usr/local/include + FINAL_LDFLAGS+= -L/usr/local/lib + FINAL_LIBS := -lmimalloc $(FINAL_LIBS) +endif + + # LIBSSL & LIBCRYPTO LIBSSL_LIBS= LIBSSL_PKGCONFIG := $(shell $(PKG_CONFIG) --exists libssl && echo $$?) diff --git a/src/server.c b/src/server.c index 02191da785..6e7f31c5ea 100644 --- a/src/server.c +++ b/src/server.c @@ -5682,7 +5682,11 @@ sds genRedisInfoString(dict *section_dict, int all_sections, int everything) { long long memory_lua = evalMemory(); long long memory_functions = functionsMemory(); struct serverMemOverhead *mh = getMemoryOverheadData(); - +#if defined(USE_JEMALLOC) + char defrag_supported[] = "yes"; +#else + char defrag_supported[] = "no"; +#endif /* Peak memory is updated from time to time by serverCron() so it * may happen that the instantaneous value is slightly bigger than * the peak value. This may confuse users, so we update the peak @@ -5757,7 +5761,8 @@ sds genRedisInfoString(dict *section_dict, int all_sections, int everything) { "mem_overhead_db_hashtable_rehashing:%zu\r\n", mh->overhead_db_hashtable_rehashing, "active_defrag_running:%d\r\n", server.active_defrag_running, "lazyfree_pending_objects:%zu\r\n", lazyfreeGetPendingObjectsCount(), - "lazyfreed_objects:%zu\r\n", lazyfreeGetFreedObjectsCount())); + "lazyfreed_objects:%zu\r\n", lazyfreeGetFreedObjectsCount(), + "defrag_supported: %s\r\n", defrag_supported)); freeMemoryOverheadData(mh); } diff --git a/src/zmalloc.c b/src/zmalloc.c index 550752240f..d1ab8969bc 100644 --- a/src/zmalloc.c +++ b/src/zmalloc.c @@ -85,6 +85,12 @@ void zlibc_free(void *ptr) { #define free(ptr) je_free(ptr) #define mallocx(size,flags) je_mallocx(size,flags) #define dallocx(ptr,flags) je_dallocx(ptr,flags) +/* Explicitly override malloc/free etc when using mimalloc. */ +#elif defined(USE_MIMALLOC) +#define malloc(size) mi_malloc(size) +#define calloc(count,size) mi_calloc(count,size) +#define realloc(ptr,size) mi_realloc(ptr,size) +#define free(ptr) mi_free(ptr) #endif #define update_zmalloc_stat_alloc(__n) atomicIncr(used_memory,(__n)) diff --git a/src/zmalloc.h b/src/zmalloc.h index 1cf4af96c4..ca93b1ea92 100644 --- a/src/zmalloc.h +++ b/src/zmalloc.h @@ -55,6 +55,19 @@ #error "Newer version of jemalloc required" #endif +#elif defined(USE_MIMALLOC) +#include +#define ZMALLOC_LIB ("mimalloc-" __xstr(MI_MALLOC_VERSION)) +#define MI_VERSION_MAJOR (MI_MALLOC_VERSION / 100) +#define MI_VERSION_MINOR ((MI_MALLOC_VERSION / 10) % 10) +#define MI_VERSION_PATCH (MI_MALLOC_VERSION % 10) +#if (MI_VERSION_MAJOR == 1 && MI_VERSION_MINOR >= 8) || (MI_VERSION_PATCH > 1) +#define HAVE_MALLOC_SIZE 1 +#define zmalloc_size(p) mi_usable_size(p) +#else +#error "Newer version of mimalloc required" +#endif + #elif defined(__APPLE__) #include #define HAVE_MALLOC_SIZE 1 diff --git a/tests/unit/other.tcl b/tests/unit/other.tcl index 503ee391a9..5e1f4f511b 100644 --- a/tests/unit/other.tcl +++ b/tests/unit/other.tcl @@ -30,6 +30,13 @@ start_server {tags {"other"}} { } } + test {INFO MEMORY: defrag_supported} { + if {[string match {*jemalloc*} [s mem_allocator]]} { + set info_mem [r info memory] + assert_equal [getInfoProperty $info_mem defrag_supported] { yes} + } + } + test {SAVE - make sure there are all the types as values} { # Wait for a background saving in progress to terminate waitForBgsave r