chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

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

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

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

mtrace分析內(nèi)存泄露

科技綠洲 ? 來源:Linux開發(fā)架構(gòu)之路 ? 作者:Linux開發(fā)架構(gòu)之路 ? 2023-11-13 10:55 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

一、mtrace分析內(nèi)存泄露

mtrace(memory trace),是 GNU Glibc 自帶的內(nèi)存問題檢測工具,它可以用來協(xié)助定位內(nèi)存泄露問題。它的實(shí)現(xiàn)源碼在glibc源碼的malloc目錄下,其基本設(shè)計(jì)原理為設(shè)計(jì)一個(gè)函數(shù) void mtrace (),函數(shù)對 libc 庫中的 malloc/free 等函數(shù)的調(diào)用進(jìn)行追蹤,由此來檢測內(nèi)存是否存在泄漏的情況。mtrace是一個(gè)C函數(shù),在里聲明及定義,函數(shù)原型為:

void mtrace(void);

mtrace原理

mtrace() 函數(shù)會(huì)為那些和動(dòng)態(tài)內(nèi)存分配有關(guān)的函數(shù)(譬如 malloc()、realloc()、memalign() 以及 free())安裝 “鉤子(hook)” 函數(shù),這些 hook 函數(shù)會(huì)為我們記錄所有有關(guān)內(nèi)存分配和釋放的跟蹤信息,而 muntrace() 則會(huì)卸載相應(yīng)的 hook 函數(shù)?;谶@些 hook 函數(shù)生成的調(diào)試跟蹤信息,我們就可以分析是否存在 “內(nèi)存泄露” 這類問題了。

設(shè)置日志生成路徑

mtrace 機(jī)制需要我們實(shí)際運(yùn)行一下程序,然后才能生成跟蹤的日志,但在實(shí)際運(yùn)行程序之前還有一件要做的事情是需要告訴 mtrace (即前文提到的 hook 函數(shù))生成日志文件的路徑。設(shè)置日志生成路徑有兩種,一種是設(shè)置環(huán)境變量:export MALLOC_TRACE=./test.log // 當(dāng)前目錄下 另一種是在代碼層面設(shè)置:setenv("MALLOC_TRACE", "output_file_name", 1);``output_file_name就是儲(chǔ)存檢測結(jié)果的文件的名稱。

測試實(shí)例

#include < mcheck.h >
#include < stdlib.h >
#include < stdio.h >

int main(int argc, char **argv)
{
    mtrace();  // 開始跟蹤

    char *p = (char *)malloc(100);
    free(p);
    p = NULL;
    p = (char *)malloc(100);

    muntrace();   // 結(jié)束跟蹤,并生成日志信息
    return 0;
}

從上述代碼中,我們希望能夠在程序開始到結(jié)束檢查內(nèi)存是否泄漏的問題,例子簡單,一眼就能看出存在內(nèi)存泄漏的問題,所以我們需要驗(yàn)證 mtrace 是否能夠檢查出來內(nèi)存泄漏問題,且檢查的結(jié)果如何分析定位。 gcc -g test.c -o test生成可執(zhí)行文件。

日志

程序運(yùn)行結(jié)束,會(huì)在當(dāng)前目錄生成 test.log 文件,打開可以看到一下內(nèi)容:

= Start
@ ./test:[0x400624] + 0x21ed450 0x64
@ ./test:[0x400634] - 0x21ed450
@ ./test:[0x400646] + 0x21ed450 0x64
= End

從這個(gè)文件中可以看出中間三行分別對應(yīng)源碼中的 malloc -> free -> malloc 操作;解讀:./test 指的是我們執(zhí)行的程序名字,[0x400624] 是第一次調(diào)用 malloc 函數(shù)機(jī)器碼中的地址信息,+ 表示申請內(nèi)存( - 表示釋放),0x21ed450 是 malloc 函數(shù)申請到的地址信息,0x64 表示的是申請的內(nèi)存大小。由此分析第一次申請已經(jīng)釋放,第二次申請沒有釋放,存在內(nèi)存泄漏的問題。

泄露分析

使用addr2line工具定位源碼位置

通過使用 "addr2line" 命令工具,得到源文件的行數(shù)(通過這個(gè)可以根據(jù)機(jī)器碼地址定位到具體源碼位置)

# addr2line -e test 0x400624
/home/test.c:9

使用mtrace工具分析日志信息

mtrace + 可執(zhí)行文件路徑 + 日志文件路徑 mtrace test ./test.log執(zhí)行,輸出如下信息:

Memory not freed:
-----------------
           Address     Size     Caller
0x00000000021ed450     0x64  at /home/test.c:14

二、Valgrind分析內(nèi)存泄露

Valgrind工具介紹

Valgrind是一套Linux下,開放源代碼(GPL V2)的仿真調(diào)試工具的集合。Valgrind由內(nèi)核(core)以及基于內(nèi)核的其他調(diào)試工具組成。內(nèi)核類似于一個(gè)框架(framework),它模擬了一個(gè)CPU環(huán)境,并提供服務(wù)給其他工具;而其他工具則類似于插件 (plug-in),利用內(nèi)核提供的服務(wù)完成各種特定的內(nèi)存調(diào)試任務(wù)。Valgrind的體系結(jié)構(gòu)如下圖所示

圖片

1、Memcheck

最常用的工具,用來檢測程序中出現(xiàn)的內(nèi)存問題,所有對內(nèi)存的讀寫都會(huì)被檢測到,一切對malloc() / free() / new / delete 的調(diào)用都會(huì)被捕獲。所以,它能檢測以下問題:對未初始化內(nèi)存的使用;讀/寫釋放后的內(nèi)存塊;讀/寫超出malloc分配的內(nèi)存塊;讀/寫不適當(dāng)?shù)臈V袃?nèi)存塊;內(nèi)存泄漏,指向一塊內(nèi)存的指針永遠(yuǎn)丟失;不正確的malloc/free或new/delete匹配;memcpy()相關(guān)函數(shù)中的dst和src指針重疊。

2、Callgrind

和 gprof 類似的分析工具,但它對程序的運(yùn)行觀察更是入微,能給我們提供更多的信息。和 gprof 不同,它不需要在編譯源代碼時(shí)附加特殊選項(xiàng),但加上調(diào)試選項(xiàng)是推薦的。Callgrind 收集程序運(yùn)行時(shí)的一些數(shù)據(jù),建立函數(shù)調(diào)用關(guān)系圖,還可以有選擇地進(jìn)行 cache 模擬。在運(yùn)行結(jié)束時(shí),它會(huì)把分析數(shù)據(jù)寫入一個(gè)文件。callgrind_annotate 可以把這個(gè)文件的內(nèi)容轉(zhuǎn)化成可讀的形式。

3、Cachegrind

Cache 分析器,它模擬 CPU 中的一級緩存 I1,Dl 和二級緩存,能夠精確地指出程序中 cache 的丟失和命中。如果需要,它還能夠?yàn)槲覀兲峁?cache 丟失次數(shù),內(nèi)存引用次數(shù),以及每行代碼,每個(gè)函數(shù),每個(gè)模塊,整個(gè)程序產(chǎn)生的指令數(shù)。這對優(yōu)化程序有很大的幫助。

4、Helgrind

它主要用來檢查多線程程序中出現(xiàn)的競爭問題。Helgrind 尋找內(nèi)存中被多個(gè)線程訪問,而又沒有一貫加鎖的區(qū)域,這些區(qū)域往往是線程之間失去同步的地方,而且會(huì)導(dǎo)致難以發(fā)掘的錯(cuò)誤。Helgrind 實(shí)現(xiàn)了名為“Eraser”的競爭檢測算法,并做了進(jìn)一步改進(jìn),減少了報(bào)告錯(cuò)誤的次數(shù)。不過,Helgrind 仍然處于實(shí)驗(yàn)階段。

5、Massif

堆棧分析器,它能測量程序在堆棧中使用了多少內(nèi)存,告訴我們堆塊,堆管理塊和棧的大小。Massif 能幫助我們減少內(nèi)存的使用,在帶有虛擬內(nèi)存的現(xiàn)代系統(tǒng)中,它還能夠加速我們程序的運(yùn)行,減少程序停留在交換區(qū)中的幾率。此外,lackey 和 nulgrind 也會(huì)提供。Lackey 是小型工具,很少用到;Nulgrind 只是為開發(fā)者展示如何創(chuàng)建一個(gè)工具。

Memcheck原理

本文的重點(diǎn)是在檢測內(nèi)存泄露,所以對于valgrind的其他工具不做過多的說明,主要說明下Memcheck的工作。Memcheck檢測內(nèi)存問題的原理如下圖所示:

圖片

Memcheck 能夠檢測出內(nèi)存問題,關(guān)鍵在于其建立了兩個(gè)全局表。

  • Valid-Value 表 對于進(jìn)程整個(gè)地址空間中的每一個(gè)字節(jié)(byte),都有與之對應(yīng)的 8個(gè)bits;對于 CPU 的每個(gè)寄存器,也有一個(gè)與之對應(yīng)的 bit 向量。這些 bits 負(fù)責(zé)記錄該字節(jié)或者寄存器值是否具有有效的、已初始化的值。
  • Valid-Address 表 對于進(jìn)程整個(gè)地址空間中的每一個(gè)字節(jié)(byte),還有與之對應(yīng)的1個(gè) bit,負(fù)責(zé)記錄該地址是否能夠被讀寫。
  • 檢測原理:當(dāng)要讀寫內(nèi)存中某個(gè)字節(jié)時(shí),首先檢查這個(gè)字節(jié)對應(yīng)的Valid-Address 表中的 A bit。如果該 A bit顯示該位置是無效位置,memcheck 則報(bào)告讀寫錯(cuò)誤。內(nèi)核(core)類似于一個(gè)虛擬的 CPU 環(huán)境,這樣當(dāng)內(nèi)存中的某個(gè)字節(jié)被加載到真實(shí)的 CPU 中時(shí),該字節(jié)對應(yīng)的Valid-Value 表中的 V bit 也被加載到虛擬的 CPU 環(huán)境中。一旦寄存器中的值,被用來產(chǎn)生內(nèi)存地址,或者該值能夠影響程序輸出,則 memcheck 會(huì)檢查對應(yīng)的V bits,如果該值尚未初始化,則會(huì)報(bào)告使用未初始化內(nèi)存錯(cuò)誤。

內(nèi)存泄露類型

valgrind 將內(nèi)存泄漏分成 4 類:

  • 確立泄露(definitely lost):運(yùn)行內(nèi)存還沒有釋放出來,但早已沒有表針偏向運(yùn)行內(nèi)存,運(yùn)行內(nèi)存早已不能瀏覽。確立泄露的運(yùn)行內(nèi)存是強(qiáng)烈要求修補(bǔ)的。
  • 間接性泄露(indirectly lost):泄露的運(yùn)行內(nèi)存表針儲(chǔ)存在確立泄露的運(yùn)行內(nèi)存中,伴隨著確立泄露的運(yùn)行內(nèi)存不能瀏覽,造成間接性泄露的運(yùn)行內(nèi)存也不能瀏覽。例如:
struct list {
 struct list *next;
};

int main(int argc, char **argv)
{
 struct list *root;
 root = (struct list *)malloc(sizeof(struct list));
 root- >next = (struct list *)malloc(sizeof(struct list));
 printf("root %p roop- >next %pn", root, root- >next);
 root = NULL;
 return 0;
}

這里遺失的是 root 表針(是確立泄露類型),造成 root 儲(chǔ)存的 next 表針變成了間接性泄露。間接性泄露的運(yùn)行內(nèi)存毫無疑問也要修補(bǔ)的,但是一般會(huì)伴隨著 確立泄露 的修補(bǔ)而修補(bǔ)。

  • 很有可能泄露(possibly lost):表針并不偏向運(yùn)行內(nèi)存頭詳細(xì)地址,只是偏向運(yùn)行內(nèi)存內(nèi)部的部位。valgrind 往往會(huì)猜疑很有可能泄露,是由于表針早已偏位,并沒有偏向運(yùn)行內(nèi)存頭,只是有運(yùn)行內(nèi)存偏位,偏向運(yùn)行內(nèi)存內(nèi)部的部位。有一些情況下,這并并不是泄露,由于這種程序流程便是那么設(shè)計(jì)方案的,比如為了更好地完成內(nèi)存對齊,附加申請辦理運(yùn)行內(nèi)存,回到兩端對齊后的內(nèi)存地址。
  • 仍可訪達(dá)(still reachable):表針一直存有且偏向運(yùn)行內(nèi)存頭頂部,直到程序流程撤出時(shí)運(yùn)行內(nèi)存還沒有釋放出來。

Valgrind參數(shù)設(shè)置

  • --leak-check= 如果設(shè)為 yes 或 full,在被調(diào)程序結(jié)束后,valgrind 會(huì)詳細(xì)敘述每一個(gè)內(nèi)存泄露情況 默認(rèn)是summary,只報(bào)道發(fā)生了幾次內(nèi)存泄露
  • --log-file=
  • --log-fd= [default: 2, stderr] valgrind 打印日志轉(zhuǎn)存到指定文件或者文件描述符。如果沒有這個(gè)參數(shù),valgrind 的日志會(huì)連同用戶程序的日志一起輸出,會(huì)顯得非常亂。
  • --trace-children= [default: no] 是否跟蹤子進(jìn)程,若是多進(jìn)程的程序,則建議使用這個(gè)功能。不過單進(jìn)程使能了也不會(huì)有多大影響。
  • --keep-debuginfo= [default: no] 如果程序有使用 動(dòng)態(tài)加載庫(dlopen),在動(dòng)態(tài)庫卸載時(shí)(dlclose),debug信息都會(huì)被清除。使能這個(gè)選項(xiàng)后,即使動(dòng)態(tài)庫被卸載,也會(huì)保留調(diào)用棧信息。
  • --keep-stacktraces= [default: alloc-and-free] 內(nèi)存泄漏不外乎申請和釋放不配對,函數(shù)調(diào)用棧是只在申請時(shí)記錄,還是在申請釋放時(shí)都記錄 如果我們只關(guān)注內(nèi)存泄漏,其實(shí)完全沒必要申請釋放都記錄,因?yàn)檫@會(huì)占用非常多的額外內(nèi)存和更多的 CPU 損耗,讓本來就執(zhí)行慢的程序雪上加霜。
  • --freelist-vol= 當(dāng)客戶程序用 free 或 delete 釋放一個(gè)內(nèi)存塊時(shí),這個(gè)內(nèi)存塊不會(huì)立即可用于再分配,它只會(huì)被放在一個(gè)freed blocks的隊(duì)列中(freelist)并被標(biāo)記為不可訪問,這樣有利于探測到在一段很重要的時(shí)間后,客戶程序又對被釋放的塊進(jìn)行訪問的錯(cuò)誤。這個(gè)選項(xiàng)規(guī)定了隊(duì)列所占的字節(jié)塊大小,默認(rèn)是20MB。增大這個(gè)選項(xiàng)的會(huì)增大memcheck的內(nèi)存開銷,但查這類錯(cuò)的能力也會(huì)提升。
  • --freelist-big-blocks= 當(dāng)從 freelist 隊(duì)列中取可用內(nèi)存塊用于再分配時(shí),memcheck 將會(huì)從那些比 number 大的內(nèi)存塊中按優(yōu)先級取出一個(gè)塊出來用。這個(gè)選項(xiàng)就防止了 freelist 中那些小的內(nèi)存塊的頻繁調(diào)用,這個(gè)選項(xiàng)提高了 查到針對小內(nèi)存塊的野指針錯(cuò)誤的幾率。若這個(gè)選項(xiàng)設(shè)為0,則所有的塊將按先進(jìn)先出的原則用于再分配。默認(rèn)是1M。參考:valgrind 簡介(內(nèi)存檢查工具)

編譯參數(shù)推薦

為了更好地在出難題時(shí)要詳盡打印出出去棧信息內(nèi)容,實(shí)際上大家最好是在編譯程序時(shí)加上 -g 選擇項(xiàng)。如果有動(dòng)態(tài)性載入的庫,必須再加上 --keep-debuginfo=yes ,不然假如發(fā)覺是動(dòng)態(tài)性載入的庫發(fā)生泄露,因?yàn)閯?dòng)態(tài)庫被卸載掉了,造成找不到符號表。編碼編譯程序提升,不建議應(yīng)用 -O2既之上。-O0很有可能會(huì)造成運(yùn)作變慢,建議使用-O1。

檢測實(shí)例說明

申請不釋放內(nèi)存

#include < stdlib.h >
#include < stdio.h >
void func()
{
  //只申請內(nèi)存而不釋放
    void *p=malloc(sizeof(int));
}
int main()
{
    func();
    return 0;
}

使用valgrind命令來執(zhí)行程序同時(shí)輸出日志到文件

valgrind --log-file=valReport --leak-check=full --show-reachable=yes --leak-resolution=low ./a.out

參數(shù)說明:

  • –log-file=valReport 是指定生成分析日志文件到當(dāng)前執(zhí)行目錄中,文件名為valReport
  • –leak-check=full 顯示每個(gè)泄露的詳細(xì)信息
  • –show-reachable=yes 是否檢測控制范圍之外的泄漏,比如全局指針、static指針等,顯示所有的內(nèi)存泄露類型
  • –leak-resolution=low 內(nèi)存泄漏報(bào)告合并等級
  • –track-origins=yes表示開啟“使用未初始化的內(nèi)存”的檢測功能,并打開詳細(xì)結(jié)果。如果沒有這句話,默認(rèn)也會(huì)做這方面的檢測,但不會(huì)打印詳細(xì)結(jié)果。執(zhí)行輸出后,報(bào)告解讀,其中54017是指進(jìn)程號,如果程序使用了多進(jìn)程的方式來執(zhí)行,那么就會(huì)顯示多個(gè)進(jìn)程的內(nèi)容。
==54017== Memcheck, a memory error detector
==54017== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==54017== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==54017== Command: ./a.out
==54017== Parent PID: 52130

第二段是對堆內(nèi)存分配的總結(jié)信息,其中提到程序一共申請了1次內(nèi)存,其中0次釋放了,4 bytes被分配(1 allocs, 0 frees, 4 bytes allocated)。在head summary中,有該程序使用的總heap內(nèi)存量,分配內(nèi)存次數(shù)和釋放內(nèi)存次數(shù),如果分配內(nèi)存次數(shù)和釋放內(nèi)存次數(shù)不一致則說明有內(nèi)存泄漏。

==54017== HEAP SUMMARY:
==54017==   in use at exit: 4 bytes in 1 blocks
==54017==   total heap usage: 1 allocs, 0 frees, 4 bytes allocated

第三段的內(nèi)容描述了內(nèi)存泄露的具體信息,其中有一塊內(nèi)存占用4字節(jié)(4 bytes in 1 blocks),在調(diào)用malloc分配,調(diào)用棧中可以看到是func函數(shù)最后調(diào)用了malloc,所以這一個(gè)信息是比較準(zhǔn)確的定位了我們泄露的內(nèi)存是在哪里申請的。

==54017== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==54017==    at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==54017==    by 0x40057E: func() (in /home/oceanstar/CLionProjects/Share/src/a.out)
==54017==    by 0x40058D: main (in /home/oceanstar/CLionProjects/Share/src/a.out)

最后這一段是總結(jié),4字節(jié)為一塊的內(nèi)存泄露

==54017== LEAK SUMMARY:
==54017==    definitely lost: 4 bytes in 1 blocks  // 確立泄露
==54017==    indirectly lost: 0 bytes in 0 blocks  // 間接性泄露
==54017==    possibly lost: 0 bytes in 0 blocks   // 很有可能泄露
==54017==    still reachable: 0 bytes in 0 blocks // 仍可訪達(dá)
==54017==    suppressed: 0 bytes in 0 blocks

讀寫越界

#include < stdio.h >
#include < iostream >
int main()
{
    int len = 5;
    int *pt = (int*)malloc(len*sizeof(int)); //problem1: not freed
    int *p = pt;
    for (int i = 0; i < len; i++){
        p++;
    }
    *p = 5; //problem2: heap block overrun
    printf("%dn", *p); //problem3: heap block overrun
    // free(pt);
    return 0;
}

problem1: 指針pt申請了空間,但是沒有釋放; problem2: pt申請了5個(gè)int的空間,p經(jīng)過5次循環(huán)已達(dá)到p[5]的位置, *p = 5時(shí),訪問越界(寫越界)。(下面valgrind報(bào)告中 Invalid write of size 4)

==58261== Invalid write of size 4
==58261==    at 0x400707: main (main.cpp:12)
==58261==  Address 0x5a23054 is 0 bytes after a block of size 20 alloc'd
==58261==    at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==58261==    by 0x4006DC: main (main.cpp:7)

problem1: 讀越界 (下面valgrind報(bào)告中 Invalid read of size 4 )

==58261== Invalid read of size 4
==58261==    at 0x400711: main (main.cpp:13)
==58261==  Address 0x5a23054 is 0 bytes after a block of size 20 alloc'd
==58261==    at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==58261==    by 0x4006DC: main (main.cpp:7)

重復(fù)釋放

#include < stdio.h >
#include < iostream >
int main()
{
    int *x;
    x = static_cast< int * >(malloc(8 * sizeof(int)));
    x = static_cast< int * >(malloc(8 * sizeof(int)));
    free(x);
    free(x);
    return 0;
}

報(bào)告如下,Invalid free() / delete / delete[] / realloc()

==59602== Invalid free() / delete / delete[] / realloc()
==59602==    at 0x4C2B06D: free (vg_replace_malloc.c:540)
==59602==    by 0x4006FE: main (main.cpp:10)
==59602==  Address 0x5a230a0 is 0 bytes inside a block of size 32 free'd
==59602==    at 0x4C2B06D: free (vg_replace_malloc.c:540)
==59602==    by 0x4006F2: main (main.cpp:9)
==59602==  Block was alloc'd at
==59602==    at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==59602==    by 0x4006E2: main (main.cpp:8)

申請釋放接口不匹配

申請釋放接口不匹配的報(bào)告如下,用malloc申請空間的指針用free釋放;用new申請的空間用delete釋放(Mismatched free() / delete / delete []):

==61950== Mismatched free() / delete / delete []
==61950==    at 0x4C2BB8F: operator delete[](void*) (vg_replace_malloc.c:651)
==61950==    by 0x4006E8: main (main.cpp:8)
==61950==  Address 0x5a23040 is 0 bytes inside a block of size 5 alloc'd
==61950==    at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==61950==    by 0x4006D1: main (main.cpp:7)

內(nèi)存覆蓋

int main()
{
    char str[11];
    for (int i = 0; i < 11; i++){
        str[i] = i;
    }
    memcpy(str + 1, str, 5);
    char x[5] = "abcd";
    strncpy(x + 2, x, 3);
}

問題出在memcpy上, 將str指針位置開始copy 5個(gè)char到str+1所指空間,會(huì)造成內(nèi)存覆蓋。strncpy也是同理。報(bào)告如下,Source and destination overlap:

==61609== Source and destination overlap in memcpy(0x1ffefffe31, 0x1ffefffe30, 5)
==61609==    at 0x4C2E81D: memcpy@@GLIBC_2.14 (vg_replace_strmem.c:1035)
==61609==    by 0x400721: main (main.cpp:11)
==61609== 
==61609== Source and destination overlap in strncpy(0x1ffefffe25, 0x1ffefffe23, 3)
==61609==    at 0x4C2D453: strncpy (vg_replace_strmem.c:552)
==61609==    by 0x400748: main (main.cpp:14)

三、總結(jié)

內(nèi)存檢測方式無非分為兩種:

1、維護(hù)一個(gè)內(nèi)存操作鏈表,當(dāng)有內(nèi)存申請操作時(shí),將其加入此鏈表中,當(dāng)有釋放操作時(shí),從申請操作從鏈表中移除。如果到程序結(jié)束后此鏈表中還有內(nèi)容,說明有內(nèi)存泄露了;如果要釋放的內(nèi)存操作沒有在鏈表中找到對應(yīng)操作,則說明是釋放了多次。使用此方法的有內(nèi)置的調(diào)試工具,Visual Leak Detecter,mtrace, memwatch, debug_new。

2、模擬進(jìn)程的地址空間。仿照操作系統(tǒng)對進(jìn)程內(nèi)存操作的處理,在用戶態(tài)下維護(hù)一個(gè)地址空間映射,此方法要求對進(jìn)程地址空間的處理有較深的理解。因?yàn)閃indows的進(jìn)程地址空間分布不是開源的,所以模擬起來很困難,因此只支持Linux。采用此方法的是valgrind。

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

    關(guān)注

    8

    文章

    678

    瀏覽量

    30852
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4400

    瀏覽量

    66365
  • C代碼
    +關(guān)注

    關(guān)注

    1

    文章

    90

    瀏覽量

    15000
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    使用valgrind對代碼進(jìn)行內(nèi)存泄露檢測

    代碼可能存在內(nèi)存泄露怎么辦?
    發(fā)表于 08-21 15:30 ?718次閱讀
    使用valgrind對代碼進(jìn)行<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄露</b>檢測

    Linux內(nèi)存泄露案例分析內(nèi)存管理分享

    作者:京東科技 李遵舉 一、問題 近期我們運(yùn)維同事接到線上LB(負(fù)載均衡)服務(wù)內(nèi)存報(bào)警,運(yùn)維同事反饋說LB集群有部分機(jī)器的內(nèi)存使用率超過80%,有的甚至超過90%,而且內(nèi)存使用率還再不停的增長。接到
    的頭像 發(fā)表于 10-24 16:14 ?1244次閱讀
    Linux<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄露</b>案例<b class='flag-5'>分析</b>和<b class='flag-5'>內(nèi)存</b>管理分享

    關(guān)于labview中的內(nèi)存泄露

    。4.最好不要用順序結(jié)構(gòu),特別是層疊式順序結(jié)構(gòu)。NI工程師評論:內(nèi)存泄露的問題,這個(gè)問題比較普遍,DAQmx任務(wù)涉及到硬件資源,凡是打開了硬件就需要及時(shí)的關(guān)閉硬件 就我個(gè)人習(xí)慣而言,如果有可能在一個(gè)程序中
    發(fā)表于 12-06 16:05

    分析你App的內(nèi)存使用之找到內(nèi)存泄露

    INSTRUMENTS調(diào)試工具的使用(二十九) —— 分析你App的內(nèi)存使用之找到內(nèi)存泄露(四)
    發(fā)表于 05-14 16:02

    內(nèi)存泄露內(nèi)存溢出是什么意思

    面試題目匯總最重要:簡單又重點(diǎn)突出的自我介紹!1、內(nèi)存泄露內(nèi)存溢出是什么意思2、static的使用3、break 和continue的區(qū)別4、指針函數(shù)和函數(shù)指針的區(qū)別5、數(shù)組和鏈表的區(qū)別
    發(fā)表于 12-20 07:47

    怎樣去解決單片機(jī)使用malloc產(chǎn)生內(nèi)存泄露的問題呢

    為什么單片機(jī)使用malloc會(huì)導(dǎo)致內(nèi)存泄露呢?怎樣去解決單片機(jī)使用malloc產(chǎn)生內(nèi)存泄露的問題呢?
    發(fā)表于 01-27 06:23

    怎么去解決paho mqtt和mymqtt的內(nèi)存泄露問題呢?

    我在使用paho mqtt和mymqtt這兩個(gè)軟件包的時(shí)候,存在內(nèi)存泄露問題。每次mqtt發(fā)送數(shù)據(jù)前后后,用free查看內(nèi)存發(fā)送前內(nèi)存情況:total memory: 441216us
    發(fā)表于 02-01 16:03

    全志R128內(nèi)存泄露調(diào)試案例

    Memleak# 使能內(nèi)存泄露分析工具 (16)Tina RTOS Memleak Backtrace Level# 內(nèi)存泄露
    發(fā)表于 12-11 10:57

    內(nèi)存溢出和內(nèi)存泄露的區(qū)別_內(nèi)存溢出的原因以及解決方法

    內(nèi)存溢出和內(nèi)存泄露的區(qū)別是什么?內(nèi)存溢出怎么解決?內(nèi)存溢出是指程序在申請內(nèi)存時(shí),沒有足夠的
    發(fā)表于 06-01 10:27 ?3158次閱讀

    記錄單片機(jī)使用malloc產(chǎn)生內(nèi)存泄露的問題及解決方法

    項(xiàng)目場景:單片機(jī)使用malloc產(chǎn)生內(nèi)存泄露的問題問題描述:bug1:創(chuàng)建了一個(gè)結(jié)構(gòu)體指針,通過malloc動(dòng)態(tài)開辟內(nèi)存的方式開辟了一段內(nèi)存空間,然后進(jìn)行寫入數(shù)據(jù)修改數(shù)據(jù)的操作,但是下
    發(fā)表于 12-03 10:21 ?9次下載
    記錄單片機(jī)使用malloc產(chǎn)生<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄露</b>的問題及解決方法

    【RT-Thread學(xué)習(xí)筆記】用memwatch排除內(nèi)存泄露

    【RT-Thread學(xué)習(xí)筆記】使用memwatch排除內(nèi)存泄露
    的頭像 發(fā)表于 07-30 14:01 ?3231次閱讀
    【RT-Thread學(xué)習(xí)筆記】用memwatch排除<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄露</b>

    Linux內(nèi)存泄漏該如何去檢測呢?

    mtrace(memory trace),是 GNU Glibc 自帶的內(nèi)存問題檢測工具,它可以用來協(xié)助定位內(nèi)存泄露問題。
    的頭像 發(fā)表于 09-21 09:37 ?1941次閱讀
    Linux<b class='flag-5'>內(nèi)存</b>泄漏該如何去檢測呢?

    如何使用valgrind對代碼進(jìn)行內(nèi)存泄露檢測

    代碼可能存在 內(nèi)存泄露 怎么辦? 使用 valgrind 可以對代碼進(jìn)行內(nèi)存泄露檢測。 valgrind下載安裝 安裝: 1 、tar –jxvf valgrind- 3 . 21 .
    的頭像 發(fā)表于 10-04 14:56 ?1409次閱讀
    如何使用valgrind對代碼進(jìn)行<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄露</b>檢測

    Linux內(nèi)存泄露案例分析

    一、問題 近期同事接到線上LB(負(fù)載均衡)服務(wù)內(nèi)存報(bào)警,同事反饋說LB集群有部分機(jī)器的內(nèi)存使用率超過80%,有的甚至超過90%,而且內(nèi)存使用率還再不停的增長。接到內(nèi)存報(bào)警的消息,讓整個(gè)
    的頭像 發(fā)表于 11-11 16:39 ?1099次閱讀
    Linux<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄露</b>案例<b class='flag-5'>分析</b>

    內(nèi)存是如何泄露

    作為 C++ 程序員,內(nèi)存泄露始終是懸在頭上的一顆炸彈。在過去幾年的 C++ 開發(fā)過程中,由于我們采用了一些技術(shù),我們的程序發(fā)生內(nèi)存泄露的情況屈指可數(shù)。今天就在這里向大家做一個(gè)簡單的介
    的頭像 發(fā)表于 11-13 14:13 ?699次閱讀
    <b class='flag-5'>內(nèi)存</b>是如何<b class='flag-5'>泄露</b>的