0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

如何使用tcmalloc來替換glibc的malloc

科技綠洲 ? 來源:Linux開發(fā)架構(gòu)之路 ? 作者:Linux開發(fā)架構(gòu)之路 ? 2023-11-11 16:52 ? 次閱讀

代碼中使用tcmalloc替換malloc

我們?nèi)绾问褂胻cmalloc來替換glibc的malloc呢?

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

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

2.在你的動態(tài)庫鏈接的地方加入:-ltcmalloc

檢測內(nèi)存泄漏

測試代碼1:

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

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

內(nèi)存泄漏檢查:env HEAPCHECK=normal ./main

結(jié)果:

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,你就得當心這里可能存在內(nèi)存泄漏,提示

Leak of 4 bytes in 1 objects allocated from

對,是有四字節(jié)的內(nèi)存泄漏,雖然你看代碼能看到指針p未釋放,但是這里你需要掌握的是在你無法直觀的通過閱讀代碼來找到內(nèi)存泄漏點的情況下,如何用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的輸出結(jié)果分析得更為直觀,輸出為text、圖片、pdf等格式。

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

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

圖片

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

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

實際上你的大多數(shù)應用都是以服務的方式啟動,長時間處于作業(yè)/工作狀態(tài)。你需要定期來檢測下內(nèi)存泄漏情況,那么這時你需要顯示的調(diào)用接口來輸出leak情況,

示例代碼2

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

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

分析使用tcmalloc后內(nèi)存暴漲不降問題

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

圖片

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

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

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

實際上我估計很多人看了官網(wǎng)說的

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

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

圖片

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

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 內(nèi)存
    +關注

    關注

    8

    文章

    2978

    瀏覽量

    73818
  • Glibc
    +關注

    關注

    0

    文章

    9

    瀏覽量

    7491
  • 動態(tài)庫
    +關注

    關注

    0

    文章

    16

    瀏覽量

    6216
  • malloc
    +關注

    關注

    0

    文章

    52

    瀏覽量

    64
收藏 人收藏

    評論

    相關推薦

    當你malloc(0)時會發(fā)生什么

    。換言之,沒事兒不要吃飽了撐的在實際編程中寫下?malloc(0)?這種天怒人怨的代碼。但是,這個無意義的問題吸引了我的興趣。因此筆者開始查閱?glibc?的源代碼,依此了解在?glibc?下
    發(fā)表于 12-01 10:42 ?466次閱讀

    Yocto Bitbake Glibc構(gòu)建失敗了怎么解決?

    我正在嘗試構(gòu)建 Yocto 映像,但在編譯 glibc 時構(gòu)建失敗。我運行了這個命令:bitbake 精簡版圖像我收到如下編譯錯誤: | /media/ubu/LocalDisk
    發(fā)表于 03-24 08:01

    全志Tina Linux下如何編譯glibc

    ./env.sh 注意下信息,我們可以看到glibc生成準備環(huán)境時候,已經(jīng)使用了我們指定gcc工具鏈,make工具。 編譯完成后,我們看到對應so庫 替換glibc,例如在我們測試demo,修改
    發(fā)表于 06-02 10:00

    使用全志方案遇到glibc庫版本低以及編譯報錯的解決方法

    env.sh腳本 env.sh ./env.sh 注意下信息,我們可以看到glibc生成準備環(huán)境時候,已經(jīng)使用了我們指定gcc工具鏈,make工具。 編譯完成后,我們看到對應so庫 替換glibc
    發(fā)表于 06-25 09:48

    通過實現(xiàn)一個簡單的malloc描述malloc背后的機制

    任何一個用過或?qū)W過C的人對malloc都不會陌生。大家都知道malloc可以分配一段連續(xù)的內(nèi)存空間,并且在不再使用時可以通過free釋放掉。但是,許多程序員對malloc背后的事情并不熟悉,許多人
    的頭像 發(fā)表于 01-27 23:30 ?4166次閱讀
    通過實現(xiàn)一個簡單的<b class='flag-5'>malloc</b><b class='flag-5'>來</b>描述<b class='flag-5'>malloc</b>背后的機制

    在嵌入式設備中使用Malloc Hook的試驗

    在嵌入式設備中,計劃使用malloc hook進行內(nèi)存跟蹤,以便測試程序的內(nèi)存使用。 試驗1: 在程序開始,增加了mtrace函數(shù),定義環(huán)境變量MALLOC_TRACE。 發(fā)現(xiàn)了
    發(fā)表于 04-02 14:37 ?680次閱讀

    glibc內(nèi)存管理存在的共性問題及解決方法

    引言 對于嵌入式設備來說,用戶態(tài)內(nèi)存管理是一項基礎功能,目前主流的用戶態(tài)內(nèi)存管理庫有glibc、uclibc、tcmalloc、jemalloc等。 本文基于glibc2.17版本進行分析,圍繞
    的頭像 發(fā)表于 06-18 14:50 ?3131次閱讀

    Glibc內(nèi)存管理之Ptmalloc2源代碼分析

    Glibc內(nèi)存管理之Ptmalloc2源代碼分析
    發(fā)表于 07-29 09:20 ?24次下載

    malloc和free簡介及實現(xiàn)方式說明

    malloc 分配指定大小的內(nèi)存空間,返回一個指向該空間的指針。大小以字節(jié)為單位。返回 void* 指針,需要強制類型轉(zhuǎn)換后才能引用其中的值。 free 釋放一個由 malloc 所分配的內(nèi)存空間。ptr 指向一個要釋放內(nèi)存的內(nèi)存塊,該指針應當是之前調(diào)用的
    的頭像 發(fā)表于 05-14 09:56 ?4509次閱讀
    <b class='flag-5'>malloc</b>和free簡介及實現(xiàn)方式說明

    如何調(diào)試glibc?

    對于GNU工具鏈開發(fā)者而言,為了獲取到一些動態(tài)重定位、函數(shù)符號解析的信息,開發(fā)者通常需要對Glibc中的動態(tài)鏈接器程序進行調(diào)試,一般會利用gdb進行調(diào)試
    的頭像 發(fā)表于 05-11 09:03 ?856次閱讀

    jemalloc分配機制的介紹及其優(yōu)化實踐

    C/C++通過libc做內(nèi)存分配。glibc中默認的分配機制是ptmalloc。除此之外,還有眾多的不同側(cè)重的優(yōu)化,例如tcmalloc,jemalloc。
    的頭像 發(fā)表于 05-30 09:12 ?1098次閱讀
    jemalloc分配機制的介紹及其優(yōu)化實踐

    面試題:malloc(0)會發(fā)生什么?

    至此,我們就可以根據(jù)這些計算出使用 glibc 在我們的電腦上運行時 malloc 出的最小空間的大小了。計算完后,還可以根據(jù) malloc_usable_size 判斷自己的計算是否正確,樣例代碼如下
    的頭像 發(fā)表于 10-31 16:27 ?477次閱讀
    面試題:<b class='flag-5'>malloc</b>(0)會發(fā)生什么?

    TCMalloc 的架構(gòu)設計細節(jié)

    本節(jié)將專注于TCMalloc 的架構(gòu)設計細節(jié),整體看一下TCMalloc 的設計特性。 主要的幾個特性如下: 高性能。大多數(shù)對象的分配和釋放都不需要產(chǎn)生太多的競爭,因為tcmalloc
    的頭像 發(fā)表于 11-09 10:18 ?372次閱讀
    <b class='flag-5'>TCMalloc</b> 的架構(gòu)設計細節(jié)

    malloc跟free的源碼分析

    malloc 本文梳理了一下malloc跟free的源碼。malloc()函數(shù)在源代碼中使用宏定義為public_mALLOc()。public_m
    的頭像 發(fā)表于 11-09 11:39 ?1531次閱讀

    如何實現(xiàn)一個malloc

    甚至把malloc當做操作系統(tǒng)所提供的系統(tǒng)調(diào)用或C的關鍵字。實際上,malloc只是C的標準庫中提供的一個普通函數(shù),而且實現(xiàn)malloc的基本思想并不復雜,任何一個對C和操作系統(tǒng)有些許了解的程序員都可以很容易理解。 這篇文章通過
    的頭像 發(fā)表于 11-13 14:31 ?728次閱讀
    如何實現(xiàn)一個<b class='flag-5'>malloc</b>