qiushao@qiushao-pc:~/projects/opensources/gperftools$ file .libs/libtcmalloc.so* .libs/libtcmalloc.so: symbolic link to libtcmalloc.so.4.5.5 .libs/libtcmalloc.so.4: symbolic link to libtcmalloc.so.4.5.5 .libs/libtcmalloc.so.4.5.5: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (GNU/Linux), dynamically linked, with debug_info, not stripped qiushao@qiushao-pc:~/projects/opensources/gperftools$
2. tcmalloc 使用
我们先在 pc 上测试一下效果,如果能满足我们的需求的话,再到板子上进行测试。 先写个有内存泄漏的 demo:
qiushao@qiushao-pc:~/projects/test$ LD_PRELOAD=/usr/local/lib/libtcmalloc.so HEAPCHECK=normal ./tcmalloc_test WARNING: Perftools heap leak checker is active -- Performance may suffer tcmalloc testdo something with buffer do something with buffer do something with buffer do something with buffer do something with buffer do something with buffer do something with buffer do something with buffer do something with buffer do something with buffer Have memory regions w/o callers: might report false leaks Leak check _main_ detected leaks of 10485760 bytes in 10 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 10485760 bytes in 10 objects allocated from: @ 55d4280a4732 @ 55d4280a4763 @ 55d4280a47d2 @ 7fc6cb53bb97 @ 55d4280a463a
If the preceding stack traces are not enough to find the leaks, try running THIS shell command:
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 lea Exiting with error code (instead of crashing) because of whole-program memory leaks qiushao@qiushao-pc:~/projects/test$
tcmalloc 的内存泄漏检查生效时会有这个警告:WARNING: Perftools heap leak checker is active -- Performance may suffer 运行完程序之后,提示: Leak of 10485760 bytes in 10 objects allocated from: 。即有 10 处内存地址泄漏了,总共泄漏了 10485760 bytes。 tcmalloc 会在 /tmp 目录下生成一个 heap 文件:/tmp/tcmalloc_test.14180.main-end.heap。这个文件记录了所有的内存分配信息。 pprof 是 gperftools 自带的一个 perl 脚本,如果我们之前有 make install 的话,直接使用就行,没有 make install 的话,就得设置一下环境变量了。 我们可以通过 pprof 脚本来解析 heap 文件,获取每一个内存泄漏的位置及调用堆栈:
qiushao@qiushao-pc:~/projects/test$ pprof ./tcmalloc_test "/tmp/tcmalloc_test.14180._main_-end.heap" --lines --text --stack Using local file ./tcmalloc_test. Using local file /tmp/tcmalloc_test.14180._main_-end.heap. Total: 10 objects Stacks:
~ # LD_PRELOAD=/vendor/lib/libtcmalloc.so HEAPCHECK=normal /vendor/bin/tcmalloc_ test WARNING: Perftools heap leak checker is active -- Performance may suffer tcmalloc testdo something with buffer do something with buffer do something with buffer do something with buffer do something with buffer do something with buffer do something with buffer do something with buffer do something with buffer do something with buffer Have memory regions w/o callers: might report false leaks Leak check _main_ detected leaks of 10485760 bytes in 10 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 10485760 bytes in 10 objects allocated from:
If the preceding stack traces are not enough to find the leaks, try running THIS shell command:
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 Exiting with error code (instead of crashing) because of whole-program memory leaks ~ #
同样也生成了 “/tmp/tcmalloc_test.251.main-end.heap” 文件。由于在板子上没法跑 pprof 脚本。这个脚本实际上是 perl 脚本,还依赖一大堆其他工具。 我们可以把 “/tmp/tcmalloc_test.251.main-end.heap” 文件 copy 到 pc 上,然后在 pc 用 pprof 进行分析。
如何替换标准库的内存分配,释放函数: LD_PRELOAD 是 Linux 系统的一个环境变量,它可以影响程序的运行时的链接,它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。一方面,我们可以以此功能来使用自己的或是更好的函数(无需别人的源码),而另一方面,我们也可以以向别人的程序注入程序,从而达到特定的目的。
如何在程序 main 函数结束后,执行内存泄漏分析: 只要定义一个全局静态类变量就行,这个变量的构造函数会在 main 之前执行,析构函数会在 main 函数之后执行。