zoukankan      html  css  js  c++  java
  • TCMalloc 安装和使用

      前面三篇译文《TCMalloc:线程缓冲的Malloc》、《使用TCMalloc的堆栈检查》、《使用TCMalloc进行堆栈分析》介绍了TCMalloc的基本原理,以及堆栈分析和检查工具,TCMalloc优点很多,比glibc 2.3的malloc快、自带的堆栈工具可以轻松找出内存瓶颈和内存泄漏,给服务器开发指明了一条新的道路。

    1.下载

      google-perftools:http://code.google.com/p/google-perftools/gperftools-2.1.tar.gz

      libunwind:http://download.savannah.gnu.org/releases/libunwind/libunwind-1.1.tar.gz

    2.libunwind安装

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

    #tar zxvf libunwind-1.1.tar.gz
    #cd libunwind-1.1
    #./configure
    #make
    #make install

    3. 安装google-perftools:

    1 #tar zxvf tar zxvf gperftools-2.1.tar.gz 
    2 #cd gperftools-2.1
    3 #./configure
    4 #make
    5 #make install

    4.TCMalloc库加载到Linux系统中:

    1 echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
    2 /sbin/ldconfig

    5.使用

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

     1 # funshion wuhan game studio
     2 # Created by zeng jun fei in 2013-08-08
     3  
     4 CXX = g++
     5 # debug
     6 CXXFLAGS =  -g -I../BaseCode -I../../CommonSrc -Wall -D_POSIX_MT_ -O0
     7 CXXLFLAGS =  -g -Wall -L../bin -lBaseCode -lpthread  -lprotobuf -rdynamic -ltcmalloc
     8   
     9 # release
    10 # CXXFLAGS =  -O3 -g -I../NetworkEngine -Wall
    11 # CXXLFLAGS =  -O3 -g -Wall -L../NetworkEngine -lnetwork
    12   
    13 LIB_NETWORK = ../bin/libBaseCode.a
    14 
    15 OBJS = $(patsubst %.cpp,%.o,$(wildcard *.cpp))
    16 SRCS = $(OBJS:%.o=%.cpp)
    17 DEPS = $(OBJS:%.o=%.d)
    18 
    19 ALL_TARGETS = ../bin/GateServer
    20 
    21 all: $(ALL_TARGETS)
    22  
    23 -include $(DEPS)
    24 $(DEPS): %.d: %.cpp
    25 @$(CXX) -MM $(CXXFLAGS) $< > $@.$$$$; sed 's,($*).o[ :]*,1.o $@ : ,g' < $@.$$$$ > $@; rm -f $@.$$$$
    26  
    27 $(OBJS): %.o: %.cpp
    28 $(CXX) -c $(CXXFLAGS) $< -o $@
    29 
    30 $(ALL_TARGETS): $(OBJS) $(LIB_NETWORK)
    31 $(CXX) $(OBJS) -o $@ $(CXXLFLAGS)
    32 
    33 clean:
    34 @rm -rf $(OBJS) $(ALL_TARGETS) *.d

    6.堆栈检查和分析

      首先,设置pperf的环境变量:export PPROF_PATH=/usr/local/bin/pprof

       测试代码:

    1 #include <iostream>
    2 using namespace std;
    3 
    4 int main()
    5 {
    6         int *p = new int();
    7        return 0;
    8 }

      编译:g++ main.cpp -o main -ltcmalloc -g -O0

      内存泄漏检查:   env HEAPCHECK=normal ./main

       结果:

    WARNING: Perftools heap leak checker is active -- Performance may suffer 
    Have memory regions w/o callers: might report false leaks 
    Leak check _main_ detected leaks of 4 bytes in 1 objects 
    The 1 largest leaks: 
    Using local file ./main. 
    Leak of 4 bytes in 1 objects allocated from: 
        @ 4007a6 main 
        @ 7f1734263d1d __libc_start_main 
        @ 4006d9 _start


    If the preceding stack traces are not enough to find the leaks, try running THIS shell command:

    pprof ./main "/tmp/main.54616._main_-end.heap" --inuse_objects --lines --heapcheck  --edgefraction=1e-10 --nodefraction=1e-10 --gv

    If you are still puzzled about why the leaks are there, try rerunning this program with HEAP_CHECK_TEST_POINTER_ALIGNMENT=1 and/or with HEAP_CHECK_MAX_POINTER_OFFSET=-1 
    If the leak report occurs in a small fraction of runs, try running with TCMALLOC_MAX_FREE_QUEUE_SIZE of few hundred MB or with TCMALLOC_RECLAIM_MEMORY=false, it might help find leaks more repeatably 
    Exiting with error code (instead of crashing) because of whole-program memory leaks 

      上面的报告显示有4个字节的内存泄漏,并提示使用pprof进一步跟踪泄漏来源的方法。 

         包括normal在内总共有4种泄漏检查方式:minimal,忽略进入main函数之前的初始化过程;normal,报告所有的无法再引用的内存对象;strick,在normal的基础上增加一些额外的检查;draconian,在程序退出的时候存在未释放的内存的情况下报错。 

      根据《使用TCMalloc的堆栈检查》,除了前面使用env命令行的全局内存泄漏检查方式外,还可以作对代码段的更加细粒度的泄漏检查。这里需要先在源代码中包含头文件google/heap-checker.h。 实例代码如下:

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cassert>
     4 #include <google/heap-checker.h>
     5 int* fun(int n)
     6 {
     7      int *p2;
     8      HeapLeakChecker heap_checker("fun");
     9     {
    10          new int[n];
    11          p2=new int[n];
    12          //delete [] p1;
    13      }
    14      assert(!heap_checker.NoLeaks());
    15      return p2;    
    16 }
    17 int main(int argc,char* argv[])
    18 {
    19        int n;
    20        scanf("%d",&n);
    21        int *p=fun(n);
    22       delete [] p;
    23 } 

      此外,还可以忽略某些已知的内存泄漏:

    1 #include 
    2 ...
    3 void *mark = HeapLeakChecker::GetDisableChecksStart();
    4 <leaky code>
    5 HeapLeakChecker::DisableChecksToHereFrom(mark);

      感觉跟valgrind效果差不多,但是valgrind还能查出内存越界,更加优秀。

    7.总结

         本来研究TCMalloc是为了优化游戏服务器,解决游戏服务器后期玩家流失后,占用大量内存的浪费,结果发现由于我们游戏服务器为了防止内存碎片和频繁调用new和delete带来的性能损耗,使用了大量的内存池对象(如装备池、技能池、玩家池),这些池都不会调用delete还给系统,所以即使使用了TCMalloc也不会有内存释放,现在也明白了服务器维护的意义,当然这和服务器框架设计很有关系,如果没有这些缓冲池,直接调用new和delete,TCMalloc会是一个很好的选择。

    原文链接:http://blog.csdn.net/chen19870707/article/details/40301783

  • 相关阅读:
    网络基本功(一)细说网络传输
    关于指针的理解
    百度地图定位,标注以及地图中心点问题
    ios 将彩色照片转化成黑白等几种类型
    在 iOS 应用中直接跳转到 AppStore 的方法
    ios中判断当前手机的网络状态
    NTFS 读写高手进阶 Windows 格式硬盘 Mac存文件 开启 ...(转载)
    tableviewcell 中使用autolayout自适应高度
    ios 3D Touch功能的实现
    一些牛人分享的ios技巧,保留着
  • 原文地址:https://www.cnblogs.com/blueoverflow/p/4928377.html
Copyright © 2011-2022 走看看