如何將 linux 默認內存分配器替換為 jemalloc
jemalloc 是 BSD 類系統的默認內存分配器,其在內存分配上比 glibc malloc 的實現更加高效,使用 jemalloc 能夠在一定程度上減少常駐程序的內存佔用,減輕內存碎片問題,提升動態內存使用效率。
通常,使用 jemalloc 的方法有兩種,一種是把 jemalloc 直接鏈接進程序,如 redis;另一種是利用 LD_PRELOAD 來使得 jemalloc 在程序運行時被預先動態加載,從而使得程序調用的 malloc/free 函數由 jemalloc 的動態庫提供,而非 libc。
方法
不過,這兩種使用方式都不太優雅。更優雅的辦法是用 jemalloc 直接在整個系統中全局替代 glibc malloc,這樣我們既不用手動改變已有程序的運行方式(如加 LD_PRELOAD),也不用在編譯新程序時主動鏈接 jemalloc,就能讓系統中幾乎所有程序在運行時使用 jemalloc。
方法:編輯/etc/ld.so.preload
,將 jemalloc 的動態庫的絕對路徑寫入此文件的首行。
比如在 Arch 上面,jemalloc 的動態庫位於/usr/lib/libjemalloc.so
,那麼把這個路徑寫入/etc/ld.so.preload
的首行即可。
原理:/etc/ld.so.preload
相當於作用系統全局的LD_PRELOAD
,所以我們的做法相當於讓系統中所有程序都在運行時被默認強制賦予了LD_PRELOAD=/usr/lib/libjemalloc.so
的環境變量。
驗證
更改完/etc/ld.so.preload
後,編寫一段含堆內存分配邏輯的 C 程序:
#include <stdlib.h>
int main() {
int *a = malloc(sizeof(int) * 100);
free(a);
return EXIT_SUCCESS;
}
直接編譯後運行:MALLOC_CONF=stats_print:true ./a.out
,應該能看到 jemalloc 的統計報告被輸出。