內存優化-使用tcmalloc分析解決內存泄漏和內存暴漲問題

2022年10月06日17:36:32 熱門 1885

下載安裝tcmalloc

#1、到google下載代碼:

當然你最好下載最新或者最穩定版本,這裡比如下載2.1版本:

wget https://gperftools.googlecode.com/files/gperftools-2.1.tar.gz

#解壓

tar -zxvf google-perftools-2.1.tar.gz

#看看說明

cd google-perftools-2.1

./configure -h

./configure

make && make install

代碼中使用tcmalloc替換malloc

我們如何使用tcmalloc來替換glibc的malloc呢?

在鏈接tcmalloc的時候我們可以使用以下任意一種方式:

1.啟動程序之前,預先加載tcmalloc動態庫的環境變量設置: exportLD_PRELOAD="/usr/local/lib/libtcmalloc.so"

2.在你的動態庫鏈接的地方加入:-ltcmalloc

檢測內存泄漏

測試代碼1:

#include <iostream>
using namespace std;
int main()
{
        int *p = new int();
        return 0;
}

編譯:g++ t.cpp -o main -ltcmalloc -g -O0

內存泄漏檢查: env HEAPCHECK=normal ./main

結果:

root@ubuntu:/home/gaoke/test# 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:
*** WARNING: Cannot convert addresses to symbols in output below.
*** Reason: Cannot find 'pprof' (is PPROF_PATH set correctly?)
*** If you cannot fix this, try running pprof directly.
Leak of 4 bytes in 1 objects allocated from:
  @ 4007ef 
  @ 7f7895a64f45 
  @ 400719 


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

pprof ./main "/tmp/main.6712._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

大家注意,這裡有關鍵字Leak,你就得當心這裡可能存在內存泄漏,提示

Leak of 4 bytes in 1 objects allocated from

對,是有四字節的內存泄漏,雖然你看代碼能看到指針p未釋放,但是這裡你需要掌握的是在你無法直觀的通過閱讀代碼來找到內存泄漏點的情況下,如何用tcmalloc工具來分析問題。

相信細心的你會注意到運行輸出的這一行

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

這裡就是我要重點講的pprof工具

google-perftool提供了一個叫pprof的工具,它是一個perl的腳本,通過這個工具,可以將google-perftool的輸出結果分析得更為直觀,輸出為text、圖片、pdf等格式。

這裡我們把結果通過text的方式輸出:你只需要把剛才的--gv換成--text

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

內存優化-使用tcmalloc分析解決內存泄漏和內存暴漲問題 - 天天要聞

好了,你可以看到這裡已經很明顯了,給你提示了t.cpp文件的第五行代碼存在內存泄漏(當然你也可以輸出其他格式,raw,png,pdf等等,whatever,只要可以幫助你去分析問題解決問題)。

實際上項目中遇到的內存泄漏問題是異常複雜的,我給的這個示例只是小試牛刀。項目常見的內存泄漏點大家都清楚,new了但是沒有得到delete,但是要根據pprof工具對應的函數,代碼行找到對應的泄漏點你可能需要花費點功夫。

實際上你的大多數應用都是以服務的方式啟動,長時間處於作業/工作狀態。你需要定期來檢測下內存泄漏情況,那麼這時你需要顯示的調用接口來輸出leak情況,

示例代碼2

bool memory_check(void* arg)
{
    HeapLeakChecker::NoGlobalLeaks();
    return TRUE;
}

將上面的代碼加到你的定時檢測邏輯里,或者需要觀察的點,那麼他就會輸出示例1中的內容,動態的幫助你分析內存泄漏點。

相關視頻推薦

內存優化-使用tcmalloc分析解決內存泄漏和內存暴漲問題 - 天天要聞

分析使用tcmalloc後內存暴漲不降問題

記得幾年前我開始推廣大家使用tcmalloc後,一些同事做壓測過程中也遇到了不少麻煩。比如當有大量數據過來,new出來很多的大塊內存,突然發現有時候內存增長到幾個G,開始以為是內存泄露的問題。

內存優化-使用tcmalloc分析解決內存泄漏和內存暴漲問題 - 天天要聞

先是用tcmalloc環境變量來檢查內存泄漏沒有找到泄漏的報告,用valgrind也做了大量的測試,但是valgrind顯示沒有內存泄露。 實際上遇到這種問題不要慌,基本上是對tcmalloc使用上的問題,你要知道默認情況下,tcmalloc會將長時間未用的內存交還系統。tcmalloc_release_rate這個flag控制了這個交回頻率。你可以在運行時通過這個語句強制這個release發生:

MallocExtension::instance()->ReleaseFreeMemory();

當然了,你可以通過 SetMemoryReleaseRate() 來設置這個tcmalloc_release_rate. 如果設置為0,代表永遠不交回。數字越大代表交回的頻率越大。一般合理的值就是設置一個0 - 10 之間的一個數。也可以通過設置環境變量 TCMALLOC_RELEASE_RATE來設置這個rate。

實際上我估計很多人看了官網說的

MallocExtension::instance()->SetMemoryReleaseRate(7.0);

很疑惑,我曾經帶着疑惑做了測試,發現SetMemoryReleaseRate設置9,10回收的內存仍然是很慢的,所以後來我索性在進程啟動的開始設置SetMemoryReleaseRate為9,然後在new對象的時候ReleaseFreeMemory,在new對象析構的時候ReleaseFreeMemory一次 (new出來的對象可能從new到delete的生命周期是不確定的,可能存在1天?4小時?30分鐘都有可能,而且不是頻繁的釋放和銷毀),因此這種情況下,內存就比較及時的回收了,所以大家可以根據自己的項目邏輯來選擇ReleaseFreeMemory的時機,最好不要頻繁的申請和釋放,這對tcmalloc來說也是難受。

內存優化-使用tcmalloc分析解決內存泄漏和內存暴漲問題 - 天天要聞

所以你不僅僅要關注tcmalloc申請大小內存塊,還要關注內存塊的在合適的時間及時回收,否則造成內存佔用過高。

熱門分類資訊推薦

曾小賢的上司Lisa榕,現實中不僅才貌雙全,還嫁給了CEO - 天天要聞

曾小賢的上司Lisa榕,現實中不僅才貌雙全,還嫁給了CEO

曾小賢的上司Lisa榕,現實中不僅才貌雙全,還嫁給了CEO雖然說《愛情公寓》這部劇在劇情上充滿了爭議,但是一定程度上,這部劇也是很多人的回憶,是伴隨了一代人的青春回憶,而且劇中的很多角色都成為了經典,他們的口頭禪也一直被拿來玩兒梗。
Lisa榕做主持多年沒紅,被陳赫拉進愛情公寓爆紅,如今怎樣了 - 天天要聞

Lisa榕做主持多年沒紅,被陳赫拉進愛情公寓爆紅,如今怎樣了

談到《愛情公寓》這部火爆一時的歡樂喜劇,大家肯定都不陌生。不知道大家是否還記得《愛情公寓》中那個把曾小賢治得服服帖帖的女上司Lisa榕,現實中的她名叫榕榕,和劇中的形象也判若兩人。1981年出生在遼寧瀋陽的榕榕,畢業於上海戲劇學院,後來成為了上海東方傳媒集團有限公司的一名主持人。