目前市面上有不少分析Jemalloc老版本的博文,但最新版本5.3.0卻少之又少。而且5.3.0的架構與5之前的版本有較大不同,本著“與時俱進”、“由淺入深”的宗旨,我將逐步分析最新release版本Jemalloc5.3.0的實現。
另外,單講實現代碼是極其枯燥的,我將盡量每個原理知識點都用一個簡簡單單的小程序引出,這樣便于大家測試和上手調試。另外,我還會用GDB打印數據結構、變量的值,方便理解當時的狀態或算法。
jemalloc留了幾個口子來配置參數,從而提高性能,我了解到的有以下四種:
- 編譯選項
- 配置文件(鏈接)?/etc/malloc.conf
- 環境變量?MALLOC_CONF
- 用戶程序中調用mallctl動態配置
下面我詳細介紹這四種配置方式,因為前面介紹了tcache,它默認是enabled的,本節我將分別用這幾種配置方式disable tcache。
?欲了解其它設置項請參考https://jemalloc.net/jemalloc.3.html
前三種方式,都是通過函數obtain_malloc_conf來拿到配置字符串的。
1.?編譯選項
還記得編譯那一篇中我們用了一個--enable-debug選項嗎?
./configure --enable-debug
configure腳本還支持很多選項,都列在了INSTALL.md中,其中有一個--with-malloc-conf可以用來配置參數。
cd jemalloc-5.3.0
./configure --with-malloc-conf="tcache:false"
make
sudo make install
像這樣就會關閉tcache功能。
用戶所給出的"tcache:false"會作為全局變量config_malloc_conf的初始值。
config_malloc_conf中tcache的值false會賦給全局變量opt_tcache以供后來使用
用戶的輸入已傳遞到opt_tcache:
之后調用如下函數在tsd中設置tcache_enabled=flase(實際為設置tsd->cant_access_tsd_items_directly_use_a_getter_or_setter_tcache_enabled=false) 。
call stack:
總結一下,數據流向為:./configure --with-malloc-conf="tcache:false" =>?config_malloc_conf =>?opt_tcache => tsd?
2. 配置文件(鏈接)?/etc/malloc.conf
ln -sf 'tcache:false' /etc/malloc.conf
執行 以上命令,/etc/malloc.conf的鏈接內容就變成了tcache:false, 注意:不是指向文件。false會先賦給全局變量opt_tcache,與第一種方式一樣之后傳給tsd。
3. 環境變量?MALLOC_CONF
環境變量可以設置全局的也可以設置臨時的,臨時的如下:
MALLOC_CONF="tcache:false" ./a.out
獲得環境變量值的代碼如下:?
之后也是把值賦值給opt_tcache, 與第一種方式一樣之后傳給tsd。
4. 用戶程序中調用mallctl動態配置
前面的辦法對一個程序來講是靜態的,一旦設定,程序中不能更改。與之相反,mallctl函數允許編程者在運行中動態改變參數值。看下面的例子。
$ cat disable_tcache.c
#include <jemalloc/jemalloc.h>
#include <stdbool.h>
#include <stdio.h>void disable_tcache() {bool tcache_enabled = false;size_t sz = sizeof(tcache_enabled);if (mallctl("thread.tcache.enabled", NULL, NULL, &tcache_enabled, sz) != 0) {perror("Error disabling tcache");}
}int main() {void *ptr1 = malloc(100); //默認tcache enableddisable_tcache(); //關閉tcachevoid *ptr2 = malloc(200); //tcache disabled.return 0;
}
實現代碼比較直接,都是mallctl調用je_ctl_byname處理不同的設置項的,本例的設置項為"thread.tcache.enabled"。