使用TCMalloc进行堆栈分析
Author:Echo Chen(陈斌)
Email:chenb19870707@gmail.com
Blog:Blog.csdn.net/chen19870707
Date:October 10th, 2014
在前一篇译文《使用TCmalloc的堆栈检查》,介绍了Tcmalloc进行堆栈检查,今天翻译《heap-profiling using tcmalloc》。了解怎样 TCmalloc进行堆栈分析。
一、堆栈分析的使用方法:
这篇技术文档描写叙述了怎样使用C++程序来分析堆栈。能够用来做一下三条事情:
- 在不论什么时间了解程序的堆栈情况
- 定位内存泄漏
- 找到大量内存分配的位置
1.链接堆栈分析器
你能够对不论什么链接了tcmalloc的程序进行堆栈分析,而且不须要又一次编译。
把tcmalloc链接到你的程序,即时你不想使用堆栈分析器来检查也是安全的。你的程序并不会执行的有不论什么一点缓慢,由于你没实用到不论什么一点堆栈分析的特性。
你能够通过LD_PRELOAD在那些不是你编译的程序中执行堆栈检查。
1: $ LD_PRELOAD="/usr/lib/libtcmalloc.so" HEAPPROFILE=...
我们不建议这样的使用。
2.开启堆栈检查
定义HEAPPROFILE环境变量来确定生成分析文件的位置。比如生成在/usr/local/nmetscape:
1: $ HEAPPROFILE=/tmp/profile /usr/local/netscape # sh
2: % setenv HEAPPROFILE /tmp/profile; /usr/local/netscape # csh
分析对子进程也是有效的:每一个子进程依据自己的名字得到它自己的分析文件(由HEAPPROFILE和进程ID组成)
出于安全的原因,堆栈检查将不会写道文件中,所以对于有setuid的程序,堆栈分析是不能使用的。
3.解压分析文件
假设堆程序中打开了堆栈分析。程序将会把分析文件生成到文件系统中。一系列分析文件的名字将被命名为例如以下:
1: <prefix>.0000.heap
2: <prefix>.0001.heap
3: <prefix>.0002.heap
4: ...
<perfix> 是HEAPPROFILE中定义的值。
注意到假设未定义文件的路径。文件将直接被生成到程序当前文件夹。
默认情况下,一个文件写满1GB换一个新的文件。
写文件的频率能够在你的程序中调用HeapProfilerSetAllocationInterval()来控制。得出这样一个结论。每一个文件的大小是一个确定的数值。
你也能够调用HeapProfile来在你程序的特定位置生成分析文件,比如:
1: extern const char* HeapProfile();
2: const char* profile = HeapProfile();
3: fputs(profile, stdout);
4: free(const_cast<char*>(profile));
4.分析了什么
这个分析系统说明了全部内存申请和释放。
它保留了每次内存分配的一系列信息。
内存分配定义为堆栈内活跃调用:malloc,calloc
,realloc
, or,new
.
5.解析profile
能够通过把分析文件传给pprof工具来得到分析输出,pprof工具能够打印CPU和堆栈使用情况。解释例如以下:
这里是一些样例,这些样例如果二进制名字为gfs_master,一系列的堆栈分析文件名称字例如以下:
profile.0001.heap profile.0002.heap ... profile.0100.heap
6.为什么进程这样大
% pprof --gv gfs_master profile.0100.heap
这个命令将会弹出一个显示分析信息的图表的窗体,例如以下是一个样例:
一些解释:
- GFS_MasterChunk::AddServer耗费掉256M内存,活跃内存为25%
- GFS_MasterChunkTable:UpdateState 消耗了176.2MB活跃内存,另外,它和被它调消耗了792MB。
在输出边缘的标签上给出了每个被调用者占用的内存。
7.比較分析文件
你常常希望跳过程序在初始化阶段的内存分配来找到内存泄漏。一个简单的方法来实现这件事情是通过比較两个分析文件,这两个文件都是从程序開始到执行了一段时间。
使用—base
option来指定第一个文件。比如:
% pprof --base=profile.0004.heap gfs_master profile.0100.heap
profile.0004.heap 中的内存使用将会见到profile.0100.heap中的内存使用。并显示出结果。
8.文本输出
% pprof gfs_master profile.0100.heap 255.6 24.7% 24.7% 255.6 24.7% GFS_MasterChunk::AddServer 184.6 17.8% 42.5% 298.8 28.8% GFS_MasterChunkTable::Create 176.2 17.0% 59.5% 729.9 70.5% GFS_MasterChunkTable::UpdateState 169.8 16.4% 75.9% 169.8 16.4% PendingClone::PendingClone 76.3 7.4% 83.3% 76.3 7.4% __default_alloc_template::_S_chunk_alloc 49.5 4.8% 88.0% 49.5 4.8% hashtable::resize ...
- 第一列包括了直接内存使用。单位是MB
- 第四列包括了它调用的模块的内存使用
- 第二列和第五列为第一列和第四列的百分比。
- 第三列为 第二列的 此行之前元素总和
9.忽略或聚焦到特定区域
例如以下的命令将会给出调用的图形显示,仅仅包括了调用图中包括了DataBuffer表达式的那些路径:
% pprof --gv --focus=DataBuffer gfs_master profile.0100.heap
相同的,以下的命令将忽略全部的路径。全部匹配了DataBuffer中的表达式的都会被忽略:
% pprof --gv --ignore=DataBuffer gfs_master profile.0100.heap
10 全部的内存分配 + 对象信息
全部前面的样例已经说明了怎样显示出空间使用,比如:那些分配了但未释放的数量。
里能够获取其他信息用例如以下标志:
--inuse_space |
Display the number of in-use megabytes (i.e. space that has been allocated but not freed). This is the default. |
--inuse_objects |
Display the number of in-use objects (i.e. number of objects that have been allocated but not freed). |
--alloc_space |
Display the number of allocated megabytes. This includes the space that has since been de-allocated. Use this if you want to find the main allocation sites in the program. |
--alloc_objects |
Display the number of allocated objects. This includes the objects that have since been de-allocated. Use this if you want to find the main allocation sites in the program. |
11.注意事项
- 堆栈分析须要使用libcmalloc
- 怎样程序链接了足够的符号信息的库。全部与之相关採样将会由上次在这个库之前发现的符号信息来负责,这就创造性的降低了符号的数量。
- 假设你在一台机器上执行程序,在还有一台机器上分析,而且这两台机器共享的库是不同的,分析输出或许会不准。
- 一些库。如STL实现,由自己的内存管理。
这回引起分析奇怪。
你必须在STL库也使用tcmalloc。所以置仅仅对少数STL实现有效。
-
Echo Chen:Blog.csdn.net/chen19870707
-