from: https://blog.intzero.net/tools/jemalloc.html
Jemalloc 不僅實現了一種通用的malloc, 還能利用它來做內存分析和監控/調優等.
這里介紹如何利用jemalloc來檢測內存泄漏問題. 並且利用LD_PRELOAD
環境變量, 可以做到不需要源代碼, 將jemalloc庫嵌入到可執行程序中, 從而用jemalloc去malloc內存, 並進行管理. 也就是說, 每當程序中調用malloc/new時, 實際調用的是jemalloc里實現的函數.
Install
從releases獲取jemalloc最新版.
參考: https://github.com/jemalloc/jemalloc/blob/dev/INSTALL.md
cd ~/jemalloc_test wget https://github.com/jemalloc/jemalloc/releases/download/5.1.0/jemalloc-5.1.0.tar.bz2 tar zxvf jemalloc-5.1.0.tar.bz2 cd jemalloc-5.1.0 ./configure --prefix=/home/intzero/jemalloc_test/jemalloc_install # 我這里裝在自己目錄下 make make install export PATH=/home/intzero/jemalloc_test/jemalloc_install/bin:$PATH
Getting Started
參考: https://github.com/jemalloc/jemalloc/wiki/Getting-Started
有幾種方式將jemalloc整合到你的程序中.
- 一種是在源代碼中加入jemalloc代碼, 在build代碼時嵌入.
- 另外一種是利用
LD_PRELOAD
環境變量, 在程序運行時就能嵌入, 不需要源代碼.
另外可以通過 MALLOC_CONF
環境變量來調整jemalloc.
寫個demo測試一下.
vi main.cpp
#include <stdlib.h> #include <iostream> #include <jemalloc/jemalloc.h> using namespace std; void do_something(size_t i) { // Leak some memory. int *p = new int[i]; // or malloc(i * 4); } int main(int argc, char **argv) { for (size_t i = 1; i <= 1000; i++) { do_something(i); } cout << "jemalloc test." << endl; // Dump allocator statistics to stderr. malloc_stats_print(NULL, NULL, NULL); return 0; }
運行:
$ g++ main.cpp -o main -I`jemalloc-config --includedir` -L`jemalloc-config --libdir` -Wl,-rpath,`jemalloc-config --libdir` -ljemalloc `jemalloc-config --libs` $ ./main
可看到打印出來的內存信息.
Leak Checking
vi main.cpp
#include <stdlib.h> #include <iostream> using namespace std; void do_something(size_t i) { // Leak some memory. int *p = new int[i]; // or malloc(i * 4); } int main(int argc, char **argv) { for (size_t i = 1; i <= 1000; i++) { do_something(i); } cout << "jemalloc test." << endl; return 0; }
運行:
$ g++ main.cpp -o main
$ MALLOC_CONF=prof_leak:true,lg_prof_sample:0,prof_final:true LD_PRELOAD=/home/intzero/jemalloc_test/jemalloc_install/lib/libjemalloc.so.2 ./main
上面這條命令會執行./main
, 並將jemalloc提前加載進去.
程序退出之后, 會生成類似jeprof.37252.0.f.heap
的文件. 查看詳細信息:
$ jeprof --show_bytes `which ./main` jeprof.37252.0.f.heap Using local file jeprof.37252.0.f.heap. Welcome to jeprof! For help, type 'help'. (jeprof) top Total: 2173680 B 2173680 100.0% 100.0% 2173680 100.0% 0x00007f8f2f7d7ac0 0 0.0% 100.0% 2173680 100.0% 0x00007f8f2e5b1b13 0 0.0% 100.0% 2173680 100.0% 0x00007f8f2f788581 0 0.0% 100.0% 2173680 100.0% 0x00007f8f2f7e93a0 0 0.0% 100.0% 2173680 100.0% _start 0 0.0% 100.0% 2173680 100.0% do_something 0 0.0% 100.0% 2173680 100.0% main (jeprof)
還可以生成call graph的PDF文件:
jeprof --show_bytes --pdf `which ./main` jeprof.37252.0.f.heap > w.pdf