1. 程式人生 > >如何在vs下linux下檢測記憶體洩露

如何在vs下linux下檢測記憶體洩露

  • 1、記憶體洩漏簡介
  • 2、Windows平臺下的記憶體洩漏檢測
    • 2.1、檢測是否存在記憶體洩漏問題
    • 2.2、定位具體的記憶體洩漏地方
  • 3、Linux平臺下的記憶體洩漏檢測 
  • 4、總結

其實Windows、Linux下面的記憶體檢測都可以單獨開篇詳細介紹,方法和工具也遠遠不止文中介紹到的,我的方法也不是最優的,如果您有更好的方法,也請您告訴我和大家。

1、記憶體洩漏簡介及後果

wikipedia中這樣定義記憶體洩漏:在電腦科學中,記憶體洩漏指由於疏忽或錯誤造成程式未能釋放已經不再使用的記憶體的情況。記憶體洩漏並非指記憶體在物理上的消失,而是應用程式分配某段記憶體後,由於設計錯誤,導致在釋放該段記憶體之前就失去了對該段記憶體的控制,從而造成了記憶體的浪費。

最難捉摸也最難檢測到的錯誤之一是記憶體洩漏,即未能正確釋放以前分配的記憶體的 bug。 只發生一次的小的記憶體洩漏可能不會被注意,但洩漏大量記憶體的程式或洩漏日益增多的程式可能會表現出各種徵兆:從效能不良(並且逐漸降低)到記憶體完全用盡。 更糟的是,洩漏的程式可能會用掉太多記憶體,以致另一個程式失敗,而使使用者無從查詢問題的真正根源。 此外,即使無害的記憶體洩漏也可能是其他問題的徵兆。

記憶體洩漏會因為減少可用記憶體的數量從而降低計算機的效能。最終,在最糟糕的情況下,過多的可用記憶體被分配掉導致全部或部分裝置停止正常工作,或者應用程式崩潰。記憶體洩漏可能不嚴重,甚至能夠被常規的手段檢測出來。在現代作業系統中,一個應用程式使用的常規記憶體在程式終止時被釋放。這表示一個短暫執行的應用程式中的記憶體洩漏不會導致嚴重後果。

在以下情況,記憶體洩漏導致較嚴重的後果:

  • 程式執行後置之不理,並且隨著時間的流失消耗越來越多的記憶體(比如伺服器上的後臺任務,尤其是嵌入式系統中的後臺任務,這些任務可能被執行後很多年內都置之不理);
  • 新的記憶體被頻繁地分配,比如當顯示電腦遊戲或動畫視訊畫面時;
  • 程式能夠請求未被釋放的記憶體(比如共享記憶體),甚至是在程式終止的時候;
  • 洩漏在作業系統內部發生;
  • 洩漏在系統關鍵驅動中發生;
  • 記憶體非常有限,比如在嵌入式系統或便攜裝置中;
  • 當運行於一個終止時記憶體並不自動釋放的作業系統(比如AmigaOS)之上,而且一旦丟失只能通過重啟來恢復。

下面我們通過以下例子來介紹如何檢測記憶體洩漏問題:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <stdlib.h> #include <iostream> using namespace std; void GetMemory(char *p, int num) { p = (char*)malloc(sizeof(char) * num);//使用new也能夠檢測出來 } int main(int argc,char** argv) { char *str = NULL; GetMemory(str, 100); cout<<"Memory leak test!"<<endl; //如果main中存在while迴圈呼叫GetMemory //那麼問題將變得很嚴重 //while(1){GetMemory(...);} return 0; }

實際中不可能這麼簡單,如果這麼簡單也用不著別的方法,程式設計師一眼就可以看出問題,此程式只用於測試。

2、Windows平臺下的記憶體洩漏檢測

2.1、檢測是否存在記憶體洩漏問題

Windows平臺下面Visual Studio 偵錯程式和 C 執行時 (CRT) 庫為我們提供了檢測和識別記憶體洩漏的有效方法,原理大致如下:記憶體分配要通過CRT在執行時實現,只要在分配記憶體和釋放記憶體時分別做好記錄,程式結束時對比分配記憶體和釋放記憶體的記錄就可以確定是不是有記憶體洩漏。在vs中啟用記憶體檢測的方法如下:

  • STEP1,在程式中包括以下語句: (#include 語句必須採用上文所示順序。 如果更改了順序,所使用的函式可能無法正常工作。)
1 2 3 #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h>

通過包括 crtdbg.h,將 malloc 和 free 函式對映到它們的除錯版本,即 _malloc_dbg 和 _free_dbg