内存泄漏分析的利器——gperftools的Heap Checker

4 篇文章 0 订阅

内存泄漏分析的利器——gperftools的Heap Checker

介绍

gperftools是Google开源的一款非常使用的性能分析工具集。主要由四个组件组成

  • Tcmalloc内存分析器
    Tcmalloc是Thread Cache malloc的缩写,号称比ptmalloc2更快的内存管理库。
    Tcmalloc原理是为每个线程单独分配一个线程本地的Cache,少量的地址分配就直接从Cache中分配,并且定期做垃圾回收,将线程本地Cache中的空闲内存返回给全局控制堆;Tcmalloc认为小于等于32K的对象是小对象,大对象直接从全局控制堆以页为单位进行分配,所以大对象总是页对齐的;Tcmalloc中一个页可以存入一些相同大小的小对象,小对象从本地内存链表中分配,大对象从中心内存堆分配。
    优势

    • 快速:相比ptmalloc2,Tcmalloc的性能成倍提升。尤其是Tcmalloc可以减少多线程之间锁的竞争问题,在小对象(32K)上能达到零竞争。
    • 占用空间小:相比ptmalloc2,tcmalloc对小对象占用空间进行了优化。例如:分配N个8字节对象只需要占用8N1.01字节的空间。即,只需要多使用1%的空间。而ptmalloc2中每个对象都需要使用一个4字节的头信息,最后占用的字节可能达到8N8。
    • 不易出现内存暴涨(ptmalloc2使用内存池,长时间没有将内存还给系统就会造成内存暴涨,tcmalloc可以通过MallocExtension::instance()->ReleaseFreeMemory()类设置内存还给系统的速度)。
  • 基于tcmalloc的堆内存检测工具Heap-profiler
    Heap-profiler是内存监控器,可以随时知道内存的使用情况。

  • 基于tcmalloc的内存泄漏分析工具Heap-checker
    Heap-checker是专门检测内存泄漏的工具,heap-checker是常用的用法是检测程序整个进程生命周期的内存泄露.

  • 基于tcmalloc实现的程序CPU性能监测工具Cpu-profiler
    Cpu-profiler主要是通过采样的的方式,给出一段时间内程序实际占用cpu时间偏进行统计和分析。

安装

  1. 从git上获取libunwind,并编译安装
git clone https://github.com/libunwind/libunwind.git
cd libunwind
sh ./autogen.sh 
./configure 
make
sudo make install
  1. 编译安装gperftools了
git clone https://github.com/gperftools/gperftools.git
sh autogen.sh 
./configure 
make
sudo make install
  1. 可视化分析工具kcachegrind
sudo apt install kcachegrind

示例

#include <stdlib.h>
 
int main() {
    const int array_count = 4;
    int* p = new int[array_count];
    return 0;
}

第5行在堆上申请了空间,但是没有释放。为了包含更多调试信息,我们使用-g方式编译该文件

g++ leak.cpp -ltcmalloc -g -o leak

注意
此处链接了tcmalloc库,它是gperftools内存问题分析方案的基础。一般来说,比较推荐链接该库,它的效率比编译器自带的内存管理库要高。
gperftools运行方式比较独特,对于heap checker工具,需要这样调用

HEAPCHECK=normal /home/fangliang/gperftools_test/heap_checker/leak


设置相关的环境变量

# which pprof
/usr/local/bin/pprof
# export PPROF_PATH=/usr/local/bin/pprof 
# env HEAPCHECK=normal   LD_PRELOAD="/usr/local/lib/libtcmalloc.so" ./test      

HEAPCHECK除了nomal外,还可以选择strict或者draconian。最后一个参数就是我们程序的路径。其分析结果展现如下

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 16 bytes in 1 objects
The 1 largest leaks:
Using local file /home/fangliang/gperftools_test/heap_checker/leak.
Leak of 16 bytes in 1 objects allocated from:
	@ 55f9903b8723 main
	@ 7fed6bbc9b97 __libc_start_main
	@ 55f9903b862a _start
 
 
If the preceding stack traces are not enough to find the leaks, try running THIS shell command:
 
pprof /home/fangliang/gperftools_test/heap_checker/leak "/tmp/leak.3384._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
Exiting with error code (instead of crashing) because of whole-program memory leaks

第6行显示我们程序有1块16字节的空间泄漏。第7到第9行,展示了泄漏处的调用堆栈。但是这个信息展现方式并没有直接指出问题产生的行数。我们可以使用其提示的第14行指令,调用可视化工具

如此,我们便可以清晰的知道,leak.cpp第5行代码申请的空间存在内存泄漏。

如果我们项目中不可以链接tcmalloc,我们还可以使用如下方式调用heap checker,其结果和上面描述的一致

LD_PRELOAD="/usr/local/lib/libtcmalloc.so" HEAPCHECK=normal /home/fangliang/gperftools_test/heap_checker/leak

检测的方式有两种
一种是需要把tcmalloc库编译进工程,
另一种不需要编译进工程,只需要在运行时通过LD_PRELOAD命令加载tcmalloc库。
官方推荐第一种方法,第二种方式存在安全问题。
第一种方式,在makefile文件中编译进tcmalloc库,运行如下命令

env PPROF_PATH=./objs/pprof HEAPCHECK=normal ./application

第二种方法,

envLD_PRELOAD="/home/zhengbin/gperf/lib/libtcmalloc.so" PPROF_PATH=../../gperf/bin/pprof HEAPCHECK=normal ./application

PPROF_PATH为检测工具路径,application为可执行程序

强杀进程会使工具失效,程序需要正常退出才会打印出相应的内存泄露信息
HEAPCHECK有四个等级minimal,normal,strick,draconian。一般来说normal能满足绝大部分使用场景了。下面是官方文档中关于四个等级的介绍

原理

valgrind是基于模拟器的技术实现,而本文介绍的gperftools则是通过在用户代码中嵌入检测代码实现的

因为工具实现原理的差异,在解决问题时也各有特长:

Valgrind:适合解决非法读写,无主内存泄露等问题定位。
gperftools:长期运行进程内存使用量应该是稳定的,gperftools适合发现运行过程中内存差异,提供泄露的函数范围。而且对影响影响小,适合高压力快速复现。

参考资料

http://gperftools.googlecode.com/svn/trunk/doc/heap_checker.html
https://github.com/gperftools/gperftools
https://blog.csdn.net/oujiangping/article/details/77172802

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值