gperltools工具集安装和使用

gperltools工具集安装和使用

简介

tcmalloc属于Gperftools工具集中的一款内存池程序库,关于google performance tools(gperftools)的安装,网络上有很多,但是自己在安装的过程还是不断的遇到问题,所以亲身体验了下,把遇到的问题记录下来,希望对其他人有用。

安装环境

  • CentOS 6.5 64bit
  • GCC 5.4 version
  • gperftools 2.0version

安装过程

  • 从github上拉去最新源码
    git clone https://github.com/gperftools/gperftools.git
  • 进入gperftools目录
    ./autogen.sh 生成configure文件
  • ./configure
  • make & make install

使用方法

  • gcc或者cmake编译选项中加入 -ltcmalloc 选项
    使用ldd查看生成的可执行程序依赖库
    有可能会出现error while loading shared libraries类似情形,因为安装默认路径为/usr/local/lib ,你可以增加软链ln -s source dest 或者
    $ echo "/usr/local/lib" > /etc/ld.so.conf
    $ ldconfig

    执行ldconfig之后,程序编译及运行时链接库文件就会去 /usr/local/lib 目录搜索 libtcmalloc.la 或libtcmalloc.so

注意:这里为了进行内存泄漏分析,一定要将TCMalloc链接在最后,官方文档里说:堆栈检查器可能误解列在它后面的链接库的一些内存。

  • 使用tcmalloc进行堆栈检查和分析(类似valgrind内存泄漏检查工具)

首先,设置pperf的环境变量:

export PPROF_PATH=/usr/local/bin/pprof

编译测试代码:

gcc main.c -o main -ltcmalloc -g -O0

内存泄漏检查:

env HEAPCHECK=normal ./main

遇到问题

  • 执行autogen报错

解决方法为 安装libtool库
yum install libtool -y

  • 如果你使用的是64操作系统需要安装libunwind库 make阶段会出现警告
    64位操作系统请先安装 libunwind库,32位操作系统不要安装。libunwind库为基于64位CPU和操作系统的程序提供了基本的堆栈辗转开解功能,其中包括用于输出堆栈跟踪的API、用于以编程方式辗转开解堆栈的API以及支持C++异常处理机制的API。

  • 死锁问题
    gperltools官方文档指出,对于x86_64平台,gperltools与libunwind搭配使用可能会导致死锁,就算没有死锁也会有其他的莫名秒的问题,反正就是问问多多,bug多多,而我现在项目测试环境刚好就是x86_64平台。当然如果只是使用tcmalloc的话,并不受影响,而我现在的工作就是内存调优,找出内存热点,内存泄漏等问题。就用上了heapprofile、heapcheck、cpuprofile等工具
    当使用heapprofile、heapcheck工具的时候发现,会导致程序进程死锁,具体原因好想是libunwind收集heap stack内存时候需要lock内存,而又需要申请内存malloc,所以会导致死锁,具体原因见官方文档github INSTALL文件说明
    怎么办呢?凉拌咯。差点就放弃去转投valgrind了,听说这货不太适合大流量环境进程的监控,而我们的程序进程就是随时都是高并发状态。
    最后INSTALL文档给出了一个下下策:
    使用-fno-omit-frame-pointer选项编译程序,并且将gperltool工具重新编译./configure
    --enable-frame-pointers

    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -Wall -g -std=c++11 -fno-omit-frame-pointer -ltcmalloc -lprofiler ")
    最后贴一下main.cpp文件

    • 使用动态插入代码的方式监控内存泄漏和内存占用遇到的不会生成dump heap文件的问题
      1. 进程启动方式无非两种,前台与后台运行,前台运行对于同时启动大量进程时并不适用了,而且随着ssh session的关闭会强制关闭进程。 后台运行的方式一般可以是 命令后加上 & (1. 直接加 2 .使用nohub 这种方式可以重定向输出并且会忽略所有挂断(SIGHUP)信号,直到系统kill -9 杀掉进程)
      2. kill -9 和 15 区别:前者会直接杀掉进程,程序不会继续执行,而后者会让程序正常结束,main函数执行到最后一行。。。
      3. 我们的内存泄漏代码刚好在最后一行,所以必须使用15 中断进程,而且不能使用nohub的方式 ,pkill默认使用15中断进程
      4. 结论:使用 & 而不是用nohub & ,使用 kill -15而不是9

发表评论

电子邮件地址不会被公开。 必填项已用*标注

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax