簡介
gperftools是谷歌的一套開源性能測試工具,可以測試內存泄露和cpu性能。相對於linux自帶的perf,gperf更加友好易用。
網址:https://github.com/gperftools/gperftools
使用
tcmalloc
作為線程池
tcmalloc提供了一個線程安全的內存池,可以鏈接到c++程序中,直接使用。它自動代替glibc的malloc,free,new,delete。
使用方法有兩種:
- 直接鏈接
g++ test.cc -ltcmallo
- 通過設置 LD_PRELOAD 環境變量來使用
LD_PRELOAD=/usr/local/lib/libtcmalloc.so ./a.out
檢測內存泄露
通過設置環境變量 HEAPCHECK,該變量支持三個值:normal (equivalent to "1"), strict, draconian
比如:
#include <iostream>
int main() {
int* p = new int[20];
return 0;
}
編譯運行:
g++ test.cc -g // 增加-g選項,可以看到內存泄露出現在哪一行
HEAPCHECK=normal LD_PRELOAD=/usr/local/lib/libtcmalloc.so ./a.out
程序輸出為:
WARNING: Perftools heap leak checker is active -- Performance may suffer
Have memory regions w/o callers: might report false leaks
Leak check _main_ detected leaks of 80 bytes in 1 objects
The 1 largest leaks:
*** WARNING: Cannot convert addresses to symbols in output below.
*** Reason: Cannot find 'pprof' (is PPROF_PATH set correctly?)
*** If you cannot fix this, try running pprof directly.
Leak of 80 bytes in 1 objects allocated from:
@ 556176d0f79c
@ 7fe7b39a2b97
@ 556176d0f6aa
If the preceding stack traces are not enough to find the leaks, try running THIS shell command:
pprof ./a.out "/tmp/a.out.11414._main_-end.heap" --inuse_objects --lines --heapcheck --edgefraction=1e-10 --nodefraction=1e-10 --gv
If you are still puzzled about why the leaks are there, try rerunning this program with HEAP_CHECK_TEST_POINTER_ALIGNMENT=1 and/or with HEAP_CHECK_MAX_POINTER_OFFSET=-1
If the leak report occurs in a small fraction of runs, try running with TCMALLOC_MAX_FREE_QUEUE_SIZE of few hundred MB or with TCMALLOC_RECLAIM_MEMORY=false, it might help find leaks more repeatab
Exiting with error code (instead of crashing) because of whole-program memory leaks
可以看到,程序給出了詳細的解釋,並給出一個shell命令,可以使用gv命令以圖形的方式詳細顯示出,內存泄露出現在哪一行,當然,需要編譯的時候,打開debug選項
我們運行給出的shell命令pprof ./a.out "/tmp/a.out.11414._main_-end.heap" --inuse_objects --lines --heapcheck --edgefraction=1e-10 --nodefraction=1e-10 --gv
cpu profiler
profile的原理是在程序運行的時候,以10ms為一個周期,對程序的堆棧進行采樣,得到每個函數的運行次數
我們需要在運行程序的時候,指定生成的 prof 文件,並通過 LD_PRELOAD 加載 libprofiler.so 動態庫
比如,運行一個