記憶體泄露探測

來源:互聯網
上載者:User

.1.           VS 2008 中記憶體泄露檢查

 

檢測記憶體流失的主要工具是調試器和 CRT 調試堆函數。若要啟用調試堆函數,請在程式中包括以下語句:

 

#define _CRTDBG_MAP_ALLOC

#include <stdlib.h>

#include <crtdbg.h>

#ifdef _DEBUG

#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)

#endif

 

 

a)      通過包括 crtdbg.h,將 malloc 和 free 函數映射到其“Debug”版本_malloc_dbg 和_free_dbg,這些函數將跟蹤記憶體配置和釋放。此映射只在調試版本(在其中定義了 _DEBUG)中發生。發布版本使用普通的 malloc 和 free 函數

b)      #define  _CRTDBG_MAP_ALLOC語句將 CRT 堆函數的基版本映射到對應的“Debug”版本。並非絕對需要該語句,但如果沒有該語句,記憶體流失轉儲包含的有用資訊將較少。

c)      在添加了上面所示語句之後,可以通過在程式中包括以下語句來轉儲記憶體流失資訊:

_CrtDumpMemoryLeaks();

當在調試器下運行程式時,_CrtDumpMemoryLeaks 將在“輸出”視窗中顯示記憶體流失資訊。記憶體流失資訊如下所示:

 

Detected memory leaks!

Dumpingobjects ->

X:XX.cpp(172): {1875} normal block at 0x00780E80, 78600 bytes long.//記憶體配置編號, 塊類型(普通、用戶端或CRT),記憶體位置,塊大小

Data: <> CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD//前 16 位元組內容(十六進位)

Object dumpcomplete.

 

----如果程式可以從多個位置退出,在程式開始包括以下調用:

 

_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF |_CRTDBG_LEAK_CHECK_DF );

該語句在程式退出時自動調用 _CrtDumpMemoryLeaks。必須同時設定 _CRTDBG_ALLOC_MEM_DF 和 _CRTDBG_LEAK_CHECK_DF 兩個位域,如上所示。

----確定記憶體泄露位置

 

添加如下一行(對於第 1875 個記憶體配置):

_crtBreakAlloc = 1875;//第1875次申請記憶體配置時

或者,可以使用具有同樣效果的 _CrtSetBreakAlloc 函數:

_CrtSetBreakAlloc(1875);

在調試狀態下運行序,在斷點停下時,開啟“呼叫堆疊”視窗,找到對應的原始碼處;

退出程式,觀察“輸出視窗”的記憶體泄露報告,看實際記憶體配置的塊號是不是和預設值相同,如果相同,就找到了;如果不同,就重複步驟3,直到相同。

 

(來源:http://blog.sina.com.cn/s/blog_4bf793ad0100jsxy.html)

 

 

2. 記憶體泄露的解決方案

   Smartpointer    ----STL中已經廣泛應用

   Garbadgecollection ----java

 

3. 記憶體泄露一般指堆記憶體泄露

   Malloc、realloc、new三種方式申請堆記憶體

   釋放方式為: free、delete

 

4. 系統資源的泄漏(resource leak)

  核心態HANDLE,GDIObject,SOCKET,Interface等,從根本上說這些由作業系統分配的對象也消耗記憶體,如果這些對象發生泄漏最終也會導致記憶體的泄漏

 

5. 如果要檢測堆記憶體的泄漏,那麼需要截獲住 malloc/realloc/free和new/delete就可以了(其實new/delete最終也是用malloc/free的,所以只要截獲前面一組即可)。對於其他的泄漏,可以採用類似的方法,截獲住相應的分配和釋放函數。比如,要檢測BSTR的泄漏,就需要截獲
SysAllocString/SysFreeString;要檢測HMENU的泄漏,就需要截獲CreateMenu/ DestroyMenu

 

6.windows平台記憶體泄露偵查工具:

MSC-Runtime Library 內建檢測功能;

第三方(外掛式)偵查工具:Purify,boundschecker;

Windows內建的performancemonitor

7. BoundsChecker

採用一種被稱為 Code Injection的技術,來截獲對分配記憶體和釋放記憶體的函數的調用。簡單地說,當你的程式開始運行時,BoundsChecker的DLL被自動載入進程的地址空間(這可以通過system-level的Hook實現),然後它會修改進程中對記憶體配置和釋放的函數調用,讓這些調用首先轉入它的代碼,然後再執行原來的代碼。BoundsChecker在做這些動作的時,無須修改被偵錯工具的原始碼或工程設定檔,這使得使用它非常的簡便、直接。

 

8.基類解構函式應聲明為virtual

RAIIà建構函式中申請資源,解構函式中釋放資源。例如:STL中的auto_ptr

 

9. 編碼規範檢查工具 CodeWizard

   內建500多條編碼規則,可隨意組合

   與vs c++無縫整合

 

10. 代碼檢查工具 PC-Lint
PC-Lint可檢查編譯器不易發現的錯誤。PC-Lint可對100多個C庫函數進行檢查,可以發現標準C/C++代碼中的1 000多個常見錯誤。

 

11. 利用Purify和Insure++尋找運行時記憶體缺陷
Rational Purify和Parasoft Insure++ 是用於執行階段錯誤檢查的工具。Purify主要檢測:數組記憶體越界讀/寫,使用未初始化的記憶體,對已釋放的記憶體進行讀/寫,記憶體流失等。Insure++ 利12.
用其專利技術(源碼插裝和運行時指標跟蹤)能夠發現大量的記憶體操作錯誤,報告錯誤的原始碼行和執行軌跡。根據筆者的測試(基於98個有各種記憶體錯誤的 C++程式,涵蓋了典型情形),Insure++ 6.1都能準確檢測。

 

利用Windows結構化異常處理機制處理髮布版本軟體的記憶體崩潰
在程式的發布階段,應盡量減少程式錯誤尤其是記憶體崩潰。如果崩潰了,應該“優雅”地退出,盡量收集程式崩潰時的運行資訊以協助程式供應商後續的調試。要捕捉記憶體非法訪問並獲知非法訪問的指令地址、寄存器內容等資訊,需要用到 Windows的結構化異常處理(Structured Exception Handling,SEH)機制[6]。MiniDumpWriteDump是dbghelp.dll提供的一個 API函數(參考MSDN),用於轉儲使用者模式程式的一些資訊(比如堆棧情況等)並存為一個檔案(比如.dmp檔案),此檔案可以被微軟的調試器
(VC++或者WinDBG)利用進行事後調試。使用此函數需要dbghelp.h、dbghelp.lib和dbghelp.dll(這些檔案可以在 Windows Platform SDK中找到)。
要事後根據.dmp檔案調試代碼,需要為發布版本軟體產生debug symbols (pdb)檔案(開啟編譯器/DEBUG選項)。在拿到.dmp檔案以後,用VC++開啟.dmp檔案,然後調試執行(按F5鍵)。這樣,崩潰現場就會重現。文獻[5]基於上述的方法實現了崩潰報告系統

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.