使用Tcmalloc进行堆栈分析

  在前一篇译文《使用TCmalloc的堆栈检查》,介绍了Tcmalloc进行堆栈检查,今天翻译《heap-profiling using tcmalloc》,了解如何 TCmalloc进行堆栈分析。html

1.堆栈分析的用法:

  这篇技术文档描述了如何使用C++程序来分析堆栈。能够用来作一下三条事情:安全

  • 在任什么时候间了解程序的堆栈状况
  • 定位内存泄漏
  • 找到大量内存分配的位置

1.1 连接堆栈分析器

  你能够对任何连接了tcmalloc的程序进行堆栈分析,而且不须要从新编译。app

  把tcmalloc连接到你的程序,即时你不想使用堆栈分析器来检查也是安全的。你的程序并不会运行的有任何一点缓慢,由于你没有用到任何一点堆栈分析的特性。工具

  你能够经过LD_PRELOAD在那些不是你编译的程序中运行堆栈检查。ui

1 $ LD_PRELOAD="/usr/lib/libtcmalloc.so" HEAPPROFILE=... 

  咱们不建议这种使用。this

1.2 开启堆栈检查

  定义HEAPPROFILE环境变量来肯定生成分析文件的位置,例如生成在/usr/local/nmetscape:spa

1 $ HEAPPROFILE=/tmp/profile /usr/local/netscape           # sh
2 % setenv HEAPPROFILE /tmp/profile; /usr/local/netscape   # csh

  分析对子进程也是有效的:每一个子进程根据本身的名字获得它本身的分析文件(由HEAPPROFILE和进程ID组成).net

  出于安全的缘由,堆栈检查将不会写道文件里,因此对于有setuid的程序,堆栈分析是不能使用的。翻译

1.3 解压分析文件

  若是堆程序中打开了堆栈分析,程序将会把分析文件生成到文件系统中,一系列分析文件的名字将被命名为以下:code

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));

1.4 分析了什么

  这个分析系统说明了全部内存申请和释放。它保留了每次内存分配的一系列信息。内存分配定义为堆栈内活跃调用:malloc,calloc,realloc, or,new.

1.5 解析profile

  能够经过把分析文件传给pprof工具来获得分析输出,pprof工具能够打印CPU和堆栈使用状况。解释以下:

  这里是一些例子,这些例子假设二进制名字为gfs_master,一系列的堆栈分析文件名字以下:

1 profile.0001.heap
2 profile.0002.heap
3 ...
4 profile.0100.heap

1.6 为何进程这样大

1 % pprof --gv gfs_master profile.0100.heap

  这个命令将会弹出一个显示分析信息的图表的窗口,以下是一个例子:

 

一些解释:

  • GFS_MasterChunk::AddServer耗费掉256M内存,活跃内存为25%
  • GFS_MasterChunkTable:UpdateState 消耗了176.2MB活跃内存,另外,它和被它调消耗了792MB。在输出边缘的标签上给出了每个被调用者占用的内存。\

1.7 比较分析文件

  你常常但愿跳过程序在初始化阶段的内存分配来找到内存泄漏。一个简单的方法来实现这件事情是经过比较两个分析文件,这两个文件都是从程序开始到运行了一段时间。使用—baseoption来指定第一个文件,例如:

1 % pprof --base=profile.0004.heap gfs_master profile.0100.heap

  profile.0004.heap 中的内存使用将会见到profile.0100.heap中的内存使用,并显示出结果。

1.8 文本输出

1 % pprof gfs_master profile.0100.heap
2    255.6  24.7%  24.7%    255.6  24.7% GFS_MasterChunk::AddServer
3    184.6  17.8%  42.5%    298.8  28.8% GFS_MasterChunkTable::Create
4    176.2  17.0%  59.5%    729.9  70.5% GFS_MasterChunkTable::UpdateState
5    169.8  16.4%  75.9%    169.8  16.4% PendingClone::PendingClone
6     76.3   7.4%  83.3%     76.3   7.4% __default_alloc_template::_S_chunk_alloc
7     49.5   4.8%  88.0%     49.5   4.8% hashtable::resize
8    ...
  • 第一列包含了直接内存使用,单位是MB
  • 第四列包含了它调用的模块的内存使用
  • 第二列和第五列为第一列和第四列的百分比。
  • 第三列为 第二列的 此行以前元素总和

1.9 忽略或聚焦到特定区域

  以下的命令将会给出调用的图形显示,只包含了调用图中包含了DataBuffer表达式的那些路径:

1 % pprof --gv --focus=DataBuffer gfs_master profile.0100.heap

  一样的,下面的命令将忽略全部的路径。全部匹配了DataBuffer中的表达式的都会被忽略: 

1 % pprof --gv --ignore=DataBuffer gfs_master profile.0100.heap

1.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.

1.11 注意事项

    • 堆栈分析须要使用libcmalloc
    • 如何程序连接了足够的符号信息的库,全部与之相关采样将会由上次在这个库以前发现的符号信息来负责,这就创造性的减小了符号的数量。
    • 若是你在一台机器上运行程序,在另外一台机器上分析,而且这两台机器共享的库是不一样的,分析输出也许会不许。
    • 一些库,如STL实现,由本身的内存管理。这回引发分析奇怪。你必须在STL库也使用tcmalloc。因此置只对少数STL实现有效。

 

原文连接:http://blog.csdn.net/chen19870707/article/details/40145565

相关文章
相关标签/搜索