使用Tcmalloc进行堆栈分析

在前一篇译文《使用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.比较分析文件

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

% 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实现有效。
时间: 2024-10-18 00:55:59

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

使用TCmalloc的堆栈检查

使用TCMalloc的堆栈检查 Author:Echo Chen(陈斌) Email:[email protected] Blog:Blog.csdn.net/chen19870707 Date:October 15th, 2014 在前一篇译文<TCMalloc:线程缓冲的Malloc>详细讲解了TCMalloc的工作原理和特点,今天翻译<heap-checking using tcmalloc>,了解Tcmalloc堆栈检查. 一.自动的内存泄漏检查 这篇技术文档描述了如何使用

java 堆栈分析

再次,研究了一个下午的jhat好jmap.从一开始惊呆.懵懂于那样大量而无聊乏味的数据,到现在有那么一点点收货.赶紧记录下来.没办法,悟性太低... C:\Users\Administrator>jps 11896 12528 Jps C:\Users\Administrator>jps 11896 19016 Jps 5060 HttpServer C:\Users\Administrator>jmap -dump:file=testJmapa 5060 Dumping heap to

java 堆栈分析4

jprofiler ,又是一款好工具... —— 不过显然,我觉得有了jvisualvm就足够了,难道它会比jvisualvm还强大很多!?? 什么时候需要它呢?它有什么特别好用的地方吗? 带来什么方便之处吗? http://www.cnblogs.com/langtianya/p/3172180.html java 堆栈分析4

java 堆栈分析2

有了mat.同时我们发现Java有提供jvisualvm, jvisualvm是一个不错的工具: heap dump . thread dump. cpu/mem profile 无所不能. 不过观察发现,对同一个java程序,其导出的hrof格式数据跟jmap导出的bin格式数据有所不同,比如String类的count,size等.应该是底层实现不同吧 同时惊人的发现jconsole竟然也可以导出hrof格式的的堆栈信息(参考http://blog.csdn.net/moneyice/arti

java 堆栈分析3

很多方式,比如jconsole.jvisualvm,或者jstack -as 这样的形式, 都可以看到实时的java堆栈的变化: eden suvirried0 suvirried1 old perganget major gc minor gc 线程 等等的变化, 但是,问题是,有了这些信息,我们能从中发现什么有价值的东西呢? 总结 虽然电脑中,java程序运行很快,但是我们总是可以获取其一举一动,任何一个细节.其运行中的蛛丝马迹,我们都可以看得清清楚楚,这就现代科技的发达!! java 堆栈

JMX堆栈分析

线程堆栈: 线程堆栈也称线程调用堆栈,是虚拟机中线程(包括锁)状态的一个瞬间快照,即系统在某一个时刻所有线程的运行状态,包括每一个线程的调用堆栈,锁的持有情况.虽然不同的虚拟机打印出来的格式有些不同,但是线程堆栈的信息都包含: 线程名字,id,线程的数量等. 线程的运行状态,锁的状态(锁被哪个线程持有,哪个线程在等待锁等) 调用堆栈(即函数的调用层次关系)调用堆栈包含完整的类名,所执行的方法,源代码的行数. 借助堆栈信息可以帮助分析很多问题,如线程死锁,锁争用,死循环,识别耗时操作等等.在多线程

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

前言 在线上的程序中,我们可能经常会碰到程序卡死或者执行很慢的情况,这时候我们希望知道是代码哪里的问题,我们或许迫切希望得到代码运行到哪里了,是哪一步很慢,是否是进入了死循环,或者是否哪一段代码有问题导致程序很慢,或者出现了线程不安全的情况,或者是某些连接数或者打开文件数太多等问题,总之我们想知道程序卡在哪里了,哪块占用了大量的资源. 此时,或许通过线程堆栈的分析就能定位出问题. 如果能深入掌握堆栈分析的技术,很多问题都能迎刃而解,但是线程堆栈分析并不简单,设计到线上的排错问题,需要有一定的知识

Go语言的堆栈分析

本文为理解翻译,原文地址:http://www.goinggo.net/2015/01/stack-traces-in-go.html Introduction 在Go语言中有一些调试技巧能帮助我们快速找到问题,有时候你想尽可能多的记录异常但仍觉得不够,搞清楚堆栈的意义有助于定位Bug或者记录更完整的信息. 本文将讨论堆栈跟踪信息以及如何在堆栈中识别函数所传递的参数. Functions 先从这段代码开始: Listing 1 01 package main 02 03 func main()

tomcat服务无响应堆栈分析

tomcat服务突然无响应了,导出内存堆栈和线程堆栈,分析后发现是同步锁使用不合理导致的. [[email protected] ~]# pgrep java10472[[email protected] ~]# jmap -heap 10472Attaching to process ID 10472, please wait...Debugger attached successfully.Server compiler detected.JVM version is 25.111-b14