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

1.堆栈分析的用法:

  这篇技术文档描述了如何使用C++程序来分析堆栈。可以用来做一下三条事情:

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

1.1 链接堆栈分析器

  你可以对任何链接了tcmalloc的程序进行堆栈分析,并且不需要重新编译。

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

  你可以通过LD_PRELOAD在那些不是你编译的程序中运行堆栈检查。

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

  我们不建议这种使用。

1.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的程序,堆栈分析是不能使用的。

1.3 解压分析文件

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

  1. <prefix>..heap
  2. <prefix>..heap
  3. <prefix>..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..heap
  2. profile..heap
  3. ...
  4. profile..heap

1.6 为什么进程这样大

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

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

一些解释:

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

1.7 比较分析文件

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

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

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

1.8 文本输出

  1. % pprof gfs_master profile..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..heap

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

  1. % pprof --gv --ignore=DataBuffer gfs_master profile..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

使用Tcmalloc进行堆栈分析的更多相关文章

  1. GDB调试32位汇编堆栈分析

    GDB调试32位汇编堆栈分析 测试源代码 #include <stdio.h> int g(int x){ return x+5; } int f(int x){ return g(x)+ ...

  2. 20145318 GDB调试汇编堆栈分析

    20145318 GDB调试汇编堆栈分析 代码 #include<stdio.h> short addend1 = 1; static int addend2 = 2; const sta ...

  3. 20145219 gdb调试汇编堆栈分析

    20145219 gdb调试汇编堆栈分析 代码gdbdemo.c int g(int x) { return x+19; } int f(int x) { return g(x); } int mai ...

  4. 20145314郑凯杰《信息安全系统设计基础》GDB调试32位汇编堆栈分析

    20145314郑凯杰<信息安全系统设计基础>GDB调试32位汇编堆栈分析 本篇博客将对第五周博客中的GDB调试32位汇编堆栈进行分析 首先放上以前环境配置的图: 图1: 测试代码: #i ...

  5. gdb运行时结合汇编堆栈分析

    一.从源代码文件到可执行文件         从C文件到可执行文件,一般来说需要两步,先将每个C文件编译成.o文件,再把多个.o文件和链接库一起链接成可执行文件.但具体来说,其实是分为四步,下面以ex ...

  6. 【转】java线上程序排错经验2 - 线程堆栈分析

    前言 在线上的程序中,我们可能经常会碰到程序卡死或者执行很慢的情况,这时候我们希望知道是代码哪里的问题,我们或许迫切希望得到代码运行到哪里了,是哪一步很慢,是否是进入了死循环,或者是否哪一段代码有问题 ...

  7. JMX堆栈分析

    线程堆栈: 线程堆栈也称线程调用堆栈,是虚拟机中线程(包括锁)状态的一个瞬间快照,即系统在某一个时刻所有线程的运行状态,包括每一个线程的调用堆栈,锁的持有情况.虽然不同的虚拟机打印出来的格式有些不同, ...

  8. 20145310 GDB调试汇编堆栈分析

    GDB调试汇编堆栈分析 由于老师说要逐条分析汇编代码,所以我学习卢肖明同学的方法,重新写了一篇博客. 代码: #include<stdio.h> short addend1 = 1; st ...

  9. Java线程堆栈分析

    不知觉间工作已有一年了,闲下来的时候总会思考下,作为一名Java程序员,不能一直停留在开发业务使用框架上面.老话说得好,机会是留给有准备的人的,因此,开始计划看一些Java底层一点的东西,尝试开始在学 ...

随机推荐

  1. <记录学习>(前三天)京东页面各种注意点

    培训学校第1到3天先学习HTML现在流行的是HTML5,目前学习的是HTML5规范.(给有基础一定的人学习)前三天学习的是京东页面的编写,和以前写的不同,页面看上去和自己写的一样,但老师讲的还是有很多 ...

  2. WinForm 窗体应用程序(进阶)之一

    进程: 进程,简单的说,就是让你的程序启动另一个程序. 1.Process.Start("calc");//启动计算器 弊端:只认识系统自带的程序,如果写错系统会崩溃. 2. // ...

  3. synchronized的实现原理-java并发编程的艺术读书笔记

    1.synchronized实现同步的基础 Java中的每个对象都是可以作为锁,具体有3种表现. 1.对于普通同步方法,锁是当前实例对象. 2.对于静态同步方法,锁是当前类的Class对象. 3.对于 ...

  4. jQuery+fullPage.js演示10种全屏滚动

    基本演示 背景演示 循环演示 回调函数演示 绑定菜单演示 项目导航演示 自动滚动 slide自动滚动 响应式 下载地址 实例代码 <!DOCTYPE html> <html lang ...

  5. jPList – 实现灵活排序和分页功能的 jQuery 插件

    jPList 是一个灵活的 jQuery 插件,可以用于任何 HTML 结构的排序,分页和筛选.它支持的数据源包括:PHP + MySQL,ASP.NET + SQL Server,PHP + SQL ...

  6. go git 安装配置与使用 (windows 7 64bit)

    go语言安装使用第三方库方式一般采用 go get github.com/.../...  命令.例如: go get github.com/astaxie/beego 1.错误情况一: packag ...

  7. go语言常用函数:cap

    cap()函数返回的是数组切片分配的空间大小.//http://www.cnblogs.com/osfipin/. package main import "fmt" func m ...

  8. 使用MDK3探测隐藏SSID名称

    先将网卡设置为监听模式. airmon-ng start wlan0 扫描附近无线网络,找出隐藏SSID的AP. airodump-ng wlan0mon 这里用下图搜到的第一个隐藏SSID做测试. ...

  9. 深入理解Objective-C Runtime

    一.简介 主要特点: 在OC语言中,函数的调用是属于动态调用的,编译阶段并不确定要调用的函数,在真正的运行时才会根据函数名查找要调用哪个函数. 而在C语言中,函数的调用是在编译阶段就已经确定要调用哪个 ...

  10. java文件复制函数

    在写代码中,经常会需要复制文件.这时候就可以把这些函数放到工具类里面. 下面是一个复制文件的函数: public class CopyFileUtil { private static String ...