一、引言
内存泄漏一般是由于程序在堆(heap)上分配了内存而没有释放,随着程序的运行占用的内存越来越大,一方面会影响程序的稳定性,可能让运行速度越来越慢,或者造成oom,甚至会影响程序所运行的机器的稳定性,造成宕机。目前有很多内存泄漏分析工具,比较经典的有valgrind, gperftools
-
valgrind直接分析非常困难,需要自己编译debug版本的、带valgrind支持的专用Python版本,而且输出的信息中大部分是Python自己的符号和调用信息,很难看出有用的信息,另外使用valgrind会让程序运行速度变得非常慢,所以不建议使用。
-
而gperftools使用简单,无需重新编译代码即可运行,对运行速度的影响也比较小。
gperftool主要支持以下四个功能:
-
thread-caching malloc(TC malloc):tcmalloc的内存分配效率要远高于malloc,可以提高高并发的性能 ,降低系统的负载
-
heap-checking:对程序是否发生内存泄露进行检测
-
heap-profiling:对程序中申请的内存区域进行监控
-
CPU profiler:对程序中各个函数使用的CPU情况进行监控探测
安装gperftool
#下载源码,解压编译安装,64位操作系统需要提前安装libunwind
#libunwind库为基于64位CPU和操作系统的程序提供了基本的堆栈辗转开解功能,其中包括用于输出堆栈跟踪的API、用于以编程方式辗转开解堆栈的API以及支持C++异常处理机制的API。
yum install libunwind-devel wget https://github.com/gperftools/gperftools/releases/download/gperftools-2.9.1/gperftools-2.9.1.tar.gz
tar -zxf gperftools-2.9.1.tar.gz
cd gperftools-2.9.1 ./configure make make install
#确认是否安装成功 $ pprof --version
二、内存泄漏检测Heap checker
使用Heap Checker,总共分为三步
-
链接tcmalloc库到应用程序中
-
运行程序
-
分析输出
2.1 链接tcmalloc库
heapchecker
是 tcmalloc 的一部分,所以为了在可执行程序中使用 heap checker
,在应用程序的链接阶段使用 -ltcmalloc
链接 tcmalloc 库。2.2 运行程序
gperftools运行方式比较独特,对于heap checker工具,我们需要这样调用
HEAPCHECK=normal your_program
HEAPCHECK除了nomal外,还可以选择minimal, strict或者draconian。最后一个参数就是我们程序的路径。
Heap checker支持四种模式:
-
minimal:在程序初始化期间(即 main 函数运行前)不进行内存泄露检查
-
normal:正常模式,通过跟踪某块内存是否可以被 live object 来访问,来判断是否出现内存泄露
-
strict:类似于 normal 模式,但是对全局对象的内存泄露有一些额外的检查
-
draconian:在该模式下,只有所有申请的内存都被释放,才认为没有出现内存泄露
2.3 分析输出
使用pprof查看内存泄漏结果,heap checker运行结束时会打印基本的泄漏信息,包括调用栈和泄漏对象的地址。除此之外,还可以使用pprof命令行工具来可视化的查看调用栈。
三、示例
-
示例程序
-
编译链接tcmalloc库
- 调用可视化工具