参考网址
http://gperftools.googlecode.com/svn/trunk/doc/heap_checker.html
heap checker 是google使用的一个内存检测工具,使用分为三步:链接tcmalloc库, 运行代码,分析输出
% env LD_PRELOAD="/usr/lib/libtcmalloc.so"如果你想使用heap checker , 那么你必须使用tcmalloc来分配内存。脱离了tcmalloc 无法使用heap checker
2, 运行代码
推荐的使用方式是“整体程序”模式,这种情况 下heap-checker在main()函数运行之前开始跟踪内存分配,在临近程序退出时再检测一次。如果它发现内存泄露,就会调用exit(1)结束该程序,并且打印如何追查内存泄露的信息。
heap-checker 在每次内存分配的时候都会记录相应堆栈跟踪信息,但是这会程序性能下降,导致内存使用大增。
“整体程序”模式检测步骤:
% env HEAPCHECK=[type] program_path eg :% env HEAPCHECK=normal /usr/local/bin/my_binary_compiled_with_tcmalloc
其中,type 可以取值normal, minimal, strict, draconian, as-is, local
3, 分析输出
#include
#include
#include
using namespace std;
int main()
{
void *p = malloc(20);
//free(p);
string *t = new string("123");
cout<<*t<
string *tt = new string[20];
delete []tt;
}
上述代码注释的地方导致内存泄露, 编译:sudo clang++ -g -ltcmalloc ./feng_test.cc -o a.out
运行:env HEAPCHECK=normal ./a.out ,输出如下:
zhfeng@zhfeng:~/Downloads/gperftools-2.2/src/tests$ env HEAPCHECK=normal ./a.out
Hooked allocator frame not found, returning empty trace
WARNING: Perftools heap leak checker is active -- Performance may suffer
123
Have memory regions w/o callers: might report false leaks
Leak check _main_ detected leaks of 56 bytes in 3 objects
The 3 largest leaks:
Using local file ./a.out.
Leak of 28 bytes in 1 objects allocated from:
@ 7fb27ca953b9 std::string::_Rep::_S_create
@ 7fb27ca96ae1 std::string::_S_construct
@ 7fb27ca96ef8 std::basic_string::basic_string
@ 400e98 main
@ 7fb27c11aec5 __libc_start_main
@ 400d64 _start
@ 0 _init
Leak of 20 bytes in 1 objects allocated from:
@ 400e4e main
@ 7fb27c11aec5 __libc_start_main
@ 400d64 _start
@ 0 _init
Leak of 8 bytes in 1 objects allocated from:
@ 400e5e main
@ 7fb27c11aec5 __libc_start_main
@ 400d64 _start
@ 0 _init
If the preceding stack traces are not enough to find the leaks, try running THIS shell command:
pprof ./a.out "/tmp/a.out.7635._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 repeatabl
Exiting with error code (instead of crashing) because of whole-program memory leaks
上面输出表明有3处内存泄露,@部分指出了调用关系和内存泄露的地址
根据提示:执行pprof ./a.out "/tmp/a.out.7635._main_-end.heap" --inuse_objects --lines --heapcheck --edgefraction=1e-10 --nodefraction=1e-10 --gv
则会借助gv 展示图表化结果,更方便定位 :
或者:pprof ./a.out "/tmp/a.out.7635._main_-end.heap" --inuse_objects --lines --heapcheck --edgefraction=1e-10 --nodefraction=1e-10 --text
zhfeng@zhfeng:~/Downloads/gperftools-2.2/src/tests$ pprof ./a.out "/tmp/a.out.5261._main_-end.heap" --inuse_objes --lines --heapcheck --edgefraction=1e-10 --nodefraction=1e-10 --text
Using local file ./a.out.
Using local file /tmp/a.out.5261._main_-end.heap.
Total: 3 objects
1 33.3% 33.3% 2 66.7% main /home/zhfeng/Downloads/gperftools-2.2/src/tests/./feng_test.cc:11
1 33.3% 66.7% 1 33.3% main /home/zhfeng/Downloads/gperftools-2.2/src/tests/./feng_test.cc:8
1 33.3% 100.0% 1 33.3% std::string::_Rep::_S_create ??:?
0 0.0% 100.0% 3 100.0% __libc_start_main /build/buildd/eglibc-2.19/csu/libc-start.c:287
0 0.0% 100.0% 3 100.0% _start ??:?
0 0.0% 100.0% 1 33.3% std::basic_string::basic_string ??:?
0 0.0% 100.0% 1 33.3% std::string::_S_construct ??:?
4, 检测局部代码内存泄露
在要被检测的代码前 ,插入一个heapleakchecker 对象,在代码块后调用该对象的NoLeaks() 方法。
但是这中方法不推荐,因为它不够智能,本人实验,某些内存泄露没有发现。
5, 对于某些已知并且能够容忍的内存泄露,可以用下述方法屏蔽heap_checker 报告:
... { HeapLeakChecker::Disabler disabler;#include} ...
6, 对于长时间运行的服务,也可以借助heap checker 分析内存泄露,限于时间不再赘述,请参考官方文档。
7, linux 多线程下heap checker 可以使用,但是有些报告并不准确。其他系统下也许不行。
8, 原理: 在检测之前保存内存使用情况到临时目录里,在最后也要保存一份,然后比对两份文件检测是否发送内存泄露。
注意: