google heap checker 介绍

参考网址

http://gperftools.googlecode.com/svn/trunk/doc/heap_checker.html


heap checker 是google使用的一个内存检测工具,使用分为三步:链接tcmalloc库, 运行代码,分析输出

  1. 链接tcmalloc库
tcmalloc 的安装略过。使用时通过 -ltcmalloc 链接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< //delete 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 展示图表化结果,更方便定位 : 

google heap checker 介绍_第1张图片

或者: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
#include
#include
#include
#include
using namespace std;

int main()
{
{
HeapLeakChecker::Disabler disabler;
void *p = malloc(20); // 该处内存泄露 不会报告
}
//free(p);
string *it = new string[10];
delete it;
string *t = new string("1idfd23");
cout<<*t< t = NULL;
//delete t;


string *tt = new string[20];
delete []tt;
}


6,  对于长时间运行的服务,也可以借助heap checker 分析内存泄露,限于时间不再赘述,请参考官方文档。

7, linux 多线程下heap checker 可以使用,但是有些报告并不准确。其他系统下也许不行。

8, 原理: 在检测之前保存内存使用情况到临时目录里,在最后也要保存一份,然后比对两份文件检测是否发送内存泄露。

注意:

sh: dot: not found 报错解决方法:sudoapt-getinstallgraphviz

安装gv: sudo apt-get install gv
其他 错误按照提示解决。


你可能感兴趣的:(google heap checker 介绍)