使用Tcmalloc進行堆棧分析

  在前一篇譯文《使用TCmalloc的堆棧檢查》,介紹了Tcmalloc進行堆棧檢查,今天翻譯《heap-profiling using tcmalloc》,瞭解如何 TCmalloc進行堆棧分析。html

1.堆棧分析的用法:

  這篇技術文檔描述瞭如何使用C++程序來分析堆棧。能夠用來作一下三條事情:安全

  • 在任什麼時候間瞭解程序的堆棧狀況
  • 定位內存泄漏
  • 找到大量內存分配的位置

1.1 連接堆棧分析器

  你能夠對任何連接了tcmalloc的程序進行堆棧分析,而且不須要從新編譯。app

  把tcmalloc連接到你的程序,即時你不想使用堆棧分析器來檢查也是安全的。你的程序並不會運行的有任何一點緩慢,由於你沒有用到任何一點堆棧分析的特性。工具

  你能夠經過LD_PRELOAD在那些不是你編譯的程序中運行堆棧檢查。ui

1 $ LD_PRELOAD="/usr/lib/libtcmalloc.so" HEAPPROFILE=... 

  咱們不建議這種使用。this

1.2 開啓堆棧檢查

  定義HEAPPROFILE環境變量來肯定生成分析文件的位置,例如生成在/usr/local/nmetscape:spa

1 $ HEAPPROFILE=/tmp/profile /usr/local/netscape           # sh
2 % setenv HEAPPROFILE /tmp/profile; /usr/local/netscape   # csh

  分析對子進程也是有效的:每一個子進程根據本身的名字獲得它本身的分析文件(由HEAPPROFILE和進程ID組成).net

  出於安全的緣由,堆棧檢查將不會寫道文件裏,因此對於有setuid的程序,堆棧分析是不能使用的。翻譯

1.3 解壓分析文件

  若是堆程序中打開了堆棧分析,程序將會把分析文件生成到文件系統中,一系列分析文件的名字將被命名爲以下:code

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));

1.4 分析了什麼

  這個分析系統說明了全部內存申請和釋放。它保留了每次內存分配的一系列信息。內存分配定義爲堆棧內活躍調用:malloc,calloc,realloc, or,new.

1.5 解析profile

  能夠經過把分析文件傳給pprof工具來獲得分析輸出,pprof工具能夠打印CPU和堆棧使用狀況。解釋以下:

  這裏是一些例子,這些例子假設二進制名字爲gfs_master,一系列的堆棧分析文件名字以下:

1 profile.0001.heap
2 profile.0002.heap
3 ...
4 profile.0100.heap

1.6 爲何進程這樣大

1 % pprof --gv gfs_master profile.0100.heap

  這個命令將會彈出一個顯示分析信息的圖表的窗口,以下是一個例子:

 

一些解釋:

  • GFS_MasterChunk::AddServer耗費掉256M內存,活躍內存爲25%
  • GFS_MasterChunkTable:UpdateState 消耗了176.2MB活躍內存,另外,它和被它調消耗了792MB。在輸出邊緣的標籤上給出了每個被調用者佔用的內存。\

1.7 比較分析文件

  你常常但願跳過程序在初始化階段的內存分配來找到內存泄漏。一個簡單的方法來實現這件事情是經過比較兩個分析文件,這兩個文件都是從程序開始到運行了一段時間。使用—baseoption來指定第一個文件,例如:

1 % pprof --base=profile.0004.heap gfs_master profile.0100.heap

  profile.0004.heap 中的內存使用將會見到profile.0100.heap中的內存使用,並顯示出結果。

1.8 文本輸出

1 % pprof gfs_master profile.0100.heap
2    255.6  24.7%  24.7%    255.6  24.7% GFS_MasterChunk::AddServer
3    184.6  17.8%  42.5%    298.8  28.8% GFS_MasterChunkTable::Create
4    176.2  17.0%  59.5%    729.9  70.5% GFS_MasterChunkTable::UpdateState
5    169.8  16.4%  75.9%    169.8  16.4% PendingClone::PendingClone
6     76.3   7.4%  83.3%     76.3   7.4% __default_alloc_template::_S_chunk_alloc
7     49.5   4.8%  88.0%     49.5   4.8% hashtable::resize
8    ...
  • 第一列包含了直接內存使用,單位是MB
  • 第四列包含了它調用的模塊的內存使用
  • 第二列和第五列爲第一列和第四列的百分比。
  • 第三列爲 第二列的 此行以前元素總和

1.9 忽略或聚焦到特定區域

  以下的命令將會給出調用的圖形顯示,只包含了調用圖中包含了DataBuffer表達式的那些路徑:

1 % pprof --gv --focus=DataBuffer gfs_master profile.0100.heap

  一樣的,下面的命令將忽略全部的路徑。全部匹配了DataBuffer中的表達式的都會被忽略: 

1 % pprof --gv --ignore=DataBuffer gfs_master profile.0100.heap

1.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.

1.11 注意事項

    • 堆棧分析須要使用libcmalloc
    • 如何程序連接了足夠的符號信息的庫,全部與之相關採樣將會由上次在這個庫以前發現的符號信息來負責,這就創造性的減小了符號的數量。
    • 若是你在一臺機器上運行程序,在另外一臺機器上分析,而且這兩臺機器共享的庫是不一樣的,分析輸出也許會不許。
    • 一些庫,如STL實現,由本身的內存管理。這回引發分析奇怪。你必須在STL庫也使用tcmalloc。因此置只對少數STL實現有效。

 

原文連接:http://blog.csdn.net/chen19870707/article/details/40145565

相關文章
相關標籤/搜索