google perftools 簡單來說就是一套用來做 memory 跟 CPU (也就是 runtime) 的 profiling tool,基本用途有三個:heap profile,單純每個看 component 的 memory 使用量;heap checker,用來檢查有沒有 memory leak;以及 CPU profile,用 sampling 的方式去探測 CPU 的使用量。這東西最大的優點就是幾乎沒有 overhead。所以比起直接用 valgrind 去跑,可以考慮先用 gperftools 先做簡單的 profiling 粗略掃描,有必要更深入檢測的話再丟給 valgrind/callgrind 去細部檢查。
安裝步驟
gperftools 支援滿多平台的,不過因為我個人自己的開發平台 & 在公司都是 linux 64-bit,以下說明就不敘述其他平台的狀況,可以直接參考他們 github 上的 INSTALL 來了解。
首先,他們開宗明義說了以下這段:
products checked into it's source repository. This is common practice for projects using autotools. As of 2.1 gperftools does not have configure and other autotools
恩,所以要先從用 autotools 產生 configure file 開始...除此之外,下面還有提到 linux 64-bit 平台上的 libc 內建 stack-unwinder 用在 gperftool 上可能有問題 (有可能會 deadlock),所以建議到這裡另外下載安裝。所以 linux 64bit 平台上的安裝步驟如下:
- 安裝 libunwind (目前最新版本已經到 1.3-rc 1囉)
- 安裝以下三套軟體:autoconf, automake, libtool (ubuntu 可以直接用 apt-get 安裝)
- $ ./autogen.sh
- $ ./configure
- $ make
- $ make check (optional,基本上是安裝前測試上一步的 make 沒有問題)
- $ make instal
簡易使用方式
heap-profile
使用 heap-profile 有兩種方法:- link 時在最後面加上 -ltcmalloc
- 設定環境變數 LD_PRELOAD 及 HEAPPROFILE
- LD_PRELOAD 是指定 libtcmalloc.so (或者是其他相關的 shared library) 所在位置,基本上可以在上面提到的安裝路徑下 (或者是你指定的位置)。document 上的舉例是這個:
- % env LD_PRELOAD="/usr/lib/libtcmalloc.so"
- HEAPPROFILE 是用來指定 profile 後的資料要放在哪。要注意的這個設定的是檔名而不是資料夾,所以要記得確定指定的路徑是否存在,不存在的話他就不做 profile 了。 document 上的例子如下,<binary> 就是要執行的執行檔
- % env HEAPPROFILE=/tmp/mybin.hprof <binary>
heap-checker
基本上跟 heap-profile 一樣,只有環境變數有點變化,改成設定 LD_PRELOAD 及 HEAPCHECK。而 HEAPCHECK 可以設定成不成的層級:- minimal:
- normal
- strict
- draconian
這邊比較值得注意的一點是:heap-checker 不能跟 heap-profile 一起使用。不過他倒是沒說如果兩個環境變數都下了會怎樣,這需要再試試看。
CPU-profile
使用方法一樣很類似,不過 library 跟環境變數略有修改:- link 時在最後面加上 -lprofiler
- 設定環境變數 LD_PRELOAD 及 CPUPROFILE
- LD_PRELOAD 要指到 libprofiler.so
- CPUPROFILE 一樣是 profling 的檔名
CPU-profile 基本上是利用 sampling 的方式來做的,方法是每隔一段時間就是看看哪個 function 正在執行,最後整理出來看誰出現比較多次。當然,這個時間間格就很重要囉,可以藉由 CPUPROFILE_FREQUENCY 這個環境變數來設一個數值決定 1 秒做幾次 sampling (預設值是 100,所以每 10ms 做一次 sampling)
pprof
基本上,上面三個 profiling 後的東西都沒辦法直接看 XD 要看 profiling 後的資料請使用 pprof 把那些資料轉換成好閱讀的格式,像是 pdf 或是 txt,而且轉成 pdf 還會依照 call graph 把資料畫成圖以便理解查看;如果是 CPU-profile 的資料的話還可以用 --callgrind 轉成 callgrind 產生的格式,然後就可以丟給 kcachegrind 開來看。另外程式如果比較大的時候也許你並不想看全部的資料,這時候可以在 pprof 的參數加上 --focus 或是 --ignore 來做篩選過濾。因為可以下的參數很多,有空再來整理過濾常用指令 Orz
Explicit Checking
有一點滿有趣的是 gperftools 因為只是一套 library,所以他其實也有開放 API 讓你直接在程式中呼叫使用,指定哪個部分是需要做 profiling 的。優點當然就是可以相當的精準,畢竟你都直接在程式裡面指明了,相對的比起上面直接在 link 或 runtime 時啟用會多費一層功,而且我想應該不會有人允許這類 code 在客戶那邊也依然會執行,因此測試結束後當然就必須要把它關掉,所以會麻煩許多。
結論
相較於 valgrind 這類雖然十分精確的 tool,但是面對太大的測資時使用起來其實沒那麼方便,因為代價太高了 (runtime 大概都是 5 ~ 10 倍計算 = =) 有時候連問題在哪都還不明確時,用 gperftools 這類可以做 profiling 的 tool 其實比較方便易用。不過因為它的 heap profiling 是藉由取代 malloc 這類 memory allocation 的 function call 為他們自己的 function 以便安插 profiling 相關的 code,所以對於有些軟體連 這類 memory allocation/deallocation 都包裝起來的情況來說,可能就無法獲得預期中的資料,是使用上要稍微注意的小細節。
沒有留言:
張貼留言