
gperftools安装与使用
0 介绍
gperftools是Google开源的一款非常使用的性能分析工具集。
主要包含五部分:
(1)TC malloc内存分析器
Tcmalloc是Thread Cache malloc的缩写,号称比ptmalloc2更快的内存管理库。
Tcmalloc原理是为每个线程单独分配一个线程本地的Cache,少量的地址分配就直接从Cache中分配,并且定期做垃圾回收,将线程本地Cache中的空闲内存返回给全局控制堆;Tcmalloc认为小于等于32K的对象是小对象,大对象直接从全局控制堆以页为单位进行分配,所以大对象总是页对齐的;Tcmalloc中一个页可以存入一些相同大小的小对象,小对象从本地内存链表中分配,大对象从中心内存堆分配。
优势:
1)快速:相比ptmalloc2,Tcmalloc的性能城北提升。尤其是Tcmalloc可以减少多线程之间锁的竞争问题,在小对象(32K)上能达到零竞争。
2)占用空间小:相比ptmalloc2,tcmalloc对小对象占用空间进行了优化。例如:分配N个8字节对象只需要占用8N*1.01字节的空间。即,只需要多使用1%的空间。而ptmalloc2中每个对象都需要使用一个4字节的头信息,最后占用的字节可能达到8N*8。
3)不易出现内存暴涨(ptmalloc2使用内存池,长时间没有将内存还给系统就会造成内存暴涨,tcmalloc可以通过MallocExtension::instance()->ReleaseFreeMemory()类设置内存还给系统的速度)。
(2)Heap-profiler
Heap-profiler是内存监控器,可以随时知道内存的使用情况[2]。
(3)Heap-checker
Heap-checker是专门检测内存泄漏的工具
(4)Cpu-profiler
Cpu-profiler主要是通过采样的的方式,给出一段时间内程序实际占用cpu时间偏进行统计和分析。
(5)pprof
pprof 是用于解析 profile 文件的 perl 脚本工具。
1 安装
1.1 安装 libunwind
下载源码,这里下载的1.6.2
wget http://mirror.rabisu.com/savannah-nongnu/libunwind/libunwind-1.6.2.tar.gz
tar -zxv -f libunwind-1.6.2.tar.gz
cd libunwind-1.6.2
./configure
make
sudo make install
1.2 安装 gperftools
下载源码:https://github.com/gperftools/gperftools/releases/download/gperftools-2.9.1/gperftools-2.9.1.tar.gz
tar -zxv -f gperftools-2.9.1.tar.gz
cd gperftools-2.9.1
./configure
make
sudo make install
1.3 更新动态库
sudo ldconfig
1.4 安装成功 pprof -v
2 内存泄露检测
2.1 源码memory_leak.cpp
#include <iostream>
int func() {
int *p = new int(10);
return 0;
}
int main() {
std::cout << "memory leak test" << std::endl;
return func();
}
2.2 编译
g++ -g memory_leak.cpp -o leak -ltcmalloc
注意:这里可能会出现找不到tcmalloc库,原因可能是没有用 ldconfig
更新动态库文件,该命令使用指南
如果是大工程,官方给出了两种方法进行链接tcmalloc库:
方法一:编译进工程,在makefile文件中编译进tcmalloc库,运行如下命令
HEAPCHECK=normal ./main
方法二:不编译进工程,只需要在运行时通过LD_PRELOAD命令加载tcmalloc库
// pprof 在环境变量中就不用写
env LD_PRELOAD="/...路径.../lib/libtcmalloc.so" PPROF_PATH=/...路径.../bin/pprof HEAPCHECK=normal ./main
注意:官方推荐第一种,第二种说不安全
2.3 运行代码
HEAPCHECK=normal ./leak
完整程序运行
的 heap checker
支持 4 种模式:
- minimal:在程序初始化期间(即 main 函数运行前)不进行内存泄露检查
- normal:正常模式,通过跟踪某块内存是否可以被
live object
来访问,来判断是否出现内存泄露 - strict:类似于
normal
模式,但是对全局对象的内存泄露有一些额外的检查 - draconian:在该模式下,只有所有申请的内存都被释放,才认为没有出现内存泄露
一般使用 normal
模式就可以满足日常要求了。
出现结果:
Leak of 10 bytes in 1 objects allocated from: // 表示有10字节的内存被泄露,但不知到什么位置,根据提示运行:
有图像界面:
pprof ./leak "/tmp/leak.442._main_-end.heap" --inuse_objects --lines --heapcheck --edgefraction=1e-10 --nodefraction=1e-10 --gv
我这里没装,将--gv去掉:
pprof ./leak "/tmp/leak.442._main_-end.heap" --inuse_objects --lines --heapcheck --edgefraction=1e-10 --nodefraction=1e-10
然后输入top即可出现位置(可以输入help,查看命令帮助):
注意:这个工具好像只有在程序正常退出时才能检测的比较完全!
参考资料:
(1)gperftools的Heap Checker_gperftools 内存泄漏_wangwangblog的博客-CSDN博客
更多推荐
所有评论(0)