Linux下記憶體洩露工具

2021-10-07 03:22:32 字數 2962 閱讀 4207

記憶體洩露(memory leak)指由於疏忽或錯誤造成程式未能釋放已經不再使用的記憶體的情況,在大型的、複雜的應用程式中,這時就出現了記憶體洩露。儘管優秀的程式設計實踐可以確保最少的洩露,但是根據經驗,當使用大量的函式對相同的記憶體塊進行處理時,很可能會出現記憶體洩露。

記憶體洩露可以分為以下幾類:

1. 常發性記憶體洩漏。發生記憶體洩露的**會被多次執行到,每次被執行的時候都會導致一塊記憶體洩露。

2. 偶發性記憶體洩露。發生記憶體洩漏的**只有在某些特定環境或操作過程下才會發生。常發性和偶發性是相對的。對於特定的環境,偶發性的也許就變成了常發性的。所以測試環境和測試方法對檢測記憶體洩露至關重要。

3.一次性記憶體洩露。發生記憶體洩露的**只會被執行一次,或者由於演算法上的缺陷,導致總會有一塊且僅一塊記憶體發生洩露。比如,在乙個singleton類的建構函式中分配記憶體,在析構函式中卻沒有釋放該記憶體。而singleton類只存在乙個例項,所以記憶體洩露只會發生一次。

4.隱式記憶體洩露。程式在執行過程中不停地分配記憶體,但是知道結束的時候才釋放記憶體。嚴格的說這裡並沒有發生記憶體洩露,因為最終程式釋放了所有申請的記憶體,但是對於乙個伺服器程式,需要執行幾天,幾周甚至幾個月,不及時釋放記憶體也可能導致耗盡系統的所有記憶體。所以,我們稱這類記憶體洩露為隱式記憶體洩漏。

現在有很多方法來檢測記憶體洩露,以下列舉了linux常用的記憶體洩露檢測工具。

應用環境: linux glibc

程式語言: c

使用方法: 包含標頭檔案mcheck.h,定義環境變數malloc_trace為輸出檔名,程式開始時呼叫mtrace()即可。

結果輸出:使用者指定的檔案

設計思路:為malloc,realloc,free函式新增鉤子函式,記錄每一對malloc-free的執行

優缺點:只能檢查使用malloc/realloc/free造成的記憶體洩露

如何獲取:glibc自帶,可直接使用

應用環境:linux

程式語言:c

使用方法: 加入memwatch.h,編譯時加上-dmemwatch -dmw_stdio及memwatch.c

結果輸出:輸出檔名稱為memwatch.log,在程式執行期間,錯誤提示都會顯示在stdout上

設計思路:將malloc/realloc/calloc/strdup/free等重定義為mwmalloc(sz, __file__, __line__)等,內部維護乙個操作鍊錶

優缺點:能檢測雙重釋放(double-free)、錯誤釋放(erroneous free)、記憶體洩露(unfreed memory)、溢位(overflow)、下溢(underflow)等等

如何獲取:

應用環境:linux

程式語言:c/c++

使用方法:編譯時加上-g選項,如gcc -g filename.c -o filename,使用如下檢測記憶體使用情況:

結果輸出: #valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./filename,就會看到記憶體使用報告

設計思路:根據軟體的記憶體操作維護乙個有效位址空間表和無效位址空間表(程序的位址空間)

優缺點:能夠檢測:

如何獲取: 

應用環境:linux/windows

程式語言:c++

結果輸出: 控制台console

設計思路:通過過載new和delete操作符來捕獲記憶體申請/釋放請求,並在程式內部維護乙個全域性靜態變數的雜湊鍊錶。在new操作符中,不僅僅分配使用者所要求的的記憶體,而是在為每次分配的記憶體都新增乙個頭部,儲存著此次分配的位置資訊和鍊錶指標,new返回的是分配的這塊記憶體加上頭部偏移後的值,而在之前已經將此返回值作了hash計算並新增到hash鍊錶中了。delete的時候先根據要釋放的指標位址做hash計算,然後再遍歷陣列hash值處的鍊錶進行查詢,如果找到則將該節點移除,未找到就abort。這樣在程式結束之後,通過檢查此陣列中是否還有未釋放的記憶體塊來確定是否有記憶體洩露。

優缺點:跨平台,僅用於c++程式。

如何獲取:

以上的這些分析工具,所使用的方法大致分為以下幾種:

1、註冊記憶體分配/釋放鉤子函式(hook)。在linux下可以malloc_hook,free_hook等5個鉤子函式,在windows下可以註冊————crtsetallochook鉤子函式,這樣在分配記憶體的時候就可以捕獲這一請求並加以處理。visual leak detecter和mtrace使用此方式。

2、使用巨集定義替換。將使用者**中的malloc,free替換為巨集定義的mwmalloc(sz, __file__, __line__)等自定義函式,從而跟蹤記憶體情趣,memwatch即使用此方式。

3、操作符過載。此方法僅用於c++語言中,通過過載new、delete操作符來實現跟蹤記憶體請求,過載後的操作符類似於鉤子函式意義。debug_new採用此方式。

這些工具的輸出方式也分以下幾種:

1、普通環境下一般輸出到除錯視窗中,很多軟體本身就提供了乙個理想的輸出場所,並且gui應用程式輸出到標準輸出時不可見的。visual leak detecter採用此法。

2、輸出到標準輸出或標準錯誤輸出:控制台應用程式可以輸出到螢幕,如memwatch, valgrind, debug_new都是採用這種方法。

3、輸出到日誌檔案:將結果輸出到使用者指定或缺省的日誌檔案中,如mtrace和memwatch

此外,這些工具的記憶體檢測方式無非也分為兩種:

1、維護乙個記憶體操作鍊錶,當有記憶體申請操作時,將其加入此煉表中,當有釋放操作時,從申請操作從鍊錶中移除。如果到程式結束後此鍊錶中還有內容,說明有記憶體洩露了;如果要釋放的記憶體操作沒有在鍊錶中找到對應操作,則說明是釋放了多次。使用此方法的有內建的除錯工具,visual leak detecter,mtrace,memwatch,debug_new。

2、模擬程序的位址空間。仿照作業系統對程序記憶體操作的處理,在使用者態下維護乙個位址空間對映,此方法要求對程序位址空間的處理有較深的理解,因為windows的程序位址空間分布不是開源的,所有模擬起來很困難,因此只支援linux。採用此方法的是valgrind。

linux下檢查記憶體洩露的工具 mtrace

最令linux程式設計師頭疼的莫過於記憶體洩露了,即使你是在優秀的程式設計師,你也不能保證所以的malloc操作都有對應的free,那必要的工具就是必不可少的了。在一般的linux發行版中,有乙個自帶的工具可以很方便的替你完成這些事,這個工具就是mtrace。下面是它的用法 可以看出,只需要在你的程...

linux下記憶體洩露檢測工具Valgrind介紹

目前在linux開發乙個分析實時路況的應用程式,在聯合測試中發現程式存在記憶體洩露的情況。這下著急了,馬上就要上線了,還好發現了一款valgrind工具,完美的解決了記憶體洩露的問題。推薦大家可以使用看看。valgrind是執行在linux上一套基於 技術的程式除錯和分析工具,它的主要作者是獲得過g...

linux下記憶體洩露檢測

前段時間遇到一些關於記憶體方面的問題,使用了malloc stats來進行記憶體檢測。呼叫函式後,函式會把輸出定向到strerr中,內容如下,arena 0 第乙個arena 每個執行緒分配乙個arena 這裡只有乙個執行緒 system bytes 135168 本執行緒從作業系統獲得的動態記憶體...