• Author:Echo Chen(陈斌)

  • Email:chenb19870707@gmail.com

  • Blog:Blog.csdn.net/chen19870707

  • Date:October 20th, 2014

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

    一、下载

    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

    二、libunwind安装

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

       1: #tar zxvf libunwind-1.1.tar.gz
       2: #cd libunwind-1.1
       3: #./configure
       4: #make
       5: #make install

    三、安装google-perftools:

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

    四、TCMalloc库加载到Linux系统中:

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

    五、使用

    在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
      35:  

    六、堆栈检查和分析

    首先,设置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:     return 0;
      24: } 

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

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

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

    七、总结

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

    -

    Echo Chen:Blog.csdn.net/chen19870707

TCMalloc 安装和使用相关推荐

  1. linux tcmalloc,内存管理TCMalloc 安装和使用

    TCMalloc(Thread-Caching Malloc)与标准glibc库的malloc实现一样的功能,但是TCMalloc在效率和速度效率都比标准malloc高很多.TCMalloc是goog ...

  2. TCMalloc解密

    原文请移步我的博客:TCMalloc解密 写在前面 本文首先简单介绍TCMalloc及其使用方法,然后解释TCMalloc替代系统的内存分配函数的原理,然后从宏观上讨论其内存分配的策略,在此之后再深入 ...

  3. tcmalloc性能测试

    一 tcmalloc简介 1.tcmalloc(thread-caching malloc),即线程缓存malloc,为每个线程分配本地的cache: 2.线程所需的小对象(几十个字节到1K左右)都从 ...

  4. C++性能优化(九) —— TCMalloc

    一.TCMalloc简介 1.TCMalloc简介 TCMalloc(Thread-Caching Malloc,线程缓存的malloc)是Google开发的内存分配算法库,最初作为Google性能工 ...

  5. MySQL 通过Tcmalloc管理内存

    一: Tcmalloc 安装 1. libunwind 安装 #如果你是在 64 位系统安装 Tcmalloc ,强烈建议先安装 libunwind,详细原因请见: https://github.co ...

  6. python list转换成array_一文掌握Python【不定期更新】

    目录 一.Numpy 1 基本操作 2 随机数 3 打乱训练数据 4 得到元素的最值 5 拼接数组 6 得到函数的信息 7 得到累乘即各项相乘的结果 8 判断一个数是否在数组中 9 数组的变换 10 ...

  7. 占内存少的java开发工具_Java所占内存中神奇的64MB

    一 前言 在生产环境,Java应用程序设置了最大JVM内存后,经常发现实际使用的内存,可能超过设置的JVM最大内存数jmap -heap pid 通过这个命令可以方便查看java的内存分配情况.一般情 ...

  8. Java内存中神奇的64MB

    一 前言 在生产环境,Java应用程序设置了最大JVM内存后,经常发现实际使用的内存,可能超过设置的JVM最大内存数jmap -heap pid 通过这个命令可以方便查看java的内存分配情况.一般情 ...

  9. de novo转录组 流程_AI-De Novo分子设计

    de novo转录组 流程 大海捞针 (Needle in a Haystack) On average, it takes ten years and costs $2.6 billion doll ...

最新文章

  1. SDN商用落地:遍地开花不代表全面实现
  2. weblogic集群的资料
  3. 监听程序配制及数据备份
  4. Handler延迟事件使用
  5. 前端:JSON.stringify() 的 5 个秘密特性
  6. JavaScript 第三课 DOM
  7. Hyper-V数据文件丢失解决方案(有图有真相)
  8. Avalonia跨平台入门第六篇之Grid动态分割
  9. 《学习R》笔记:科学计算器、检查变量和工作区、向量、矩阵和数组、列表和数据框...
  10. 传递function_JS中!function(){}()的理解
  11. Chrome 谷歌浏览器账户无法登录、注册
  12. 二叉树前中后序遍历及其本质
  13. 各种泵的图形符号_水泵cad画法
  14. sns java_JEESNS首页、文档和下载 - Java 开源 SNS 社区系统
  15. 微信h5开发网页授权-本地如何开发调试?
  16. ENSP下载还有其他资料地址
  17. 计算机仿真软件multisim,电路仿真软件哪个好?2019电路仿真软件推荐
  18. 乐高收割机器人_乐高机器人这个大坑,为啥大家都拽着孩子往里跳?
  19. 小程序轮播图swiper补充
  20. 七剑下天山-告别时域分析的过渡课堂练习-SS2022s

热门文章

  1. android 反编译 脱壳,反编译、回编译、脱壳的简单测试
  2. 微信界面Android开发
  3. 山东大学软件学院数据结构复习题目
  4. 深度强化学习系列(1): 深度强化学习概述
  5. java 图片格式转化 wmf,emf 转 svg,png
  6. 微信小程序 滚动列表(无限滚动)
  7. 【安全知识分享】安全生产责任制培训.pptx(附下载)
  8. Django建站 - 模板篇
  9. keras搭建Unet实现图像分割
  10. opencv生成日志_opencv数据写入txt文件