TCMalloc 安裝和使用

  前面三篇譯文《TCMalloc:線程緩衝的Malloc》、《使用TCMalloc的堆棧檢查》、《使用TCMalloc進行堆棧分析》介紹了TCMalloc的基本原理,以及堆棧分析和檢查工具,TCMalloc優勢不少,比glibc 2.3的malloc快、自帶的堆棧工具能夠輕鬆找出內存瓶頸和內存泄漏,給服務器開發指明瞭一條新的道路。node

1.下載

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

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

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/pprofapp

   測試代碼:框架

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

相關文章
相關標籤/搜索