windows應用進程中堆泄漏檢測的簡單分析和補充

來源:互聯網
上載者:User

一般來說,當一個應用進程存在存在記憶體流失的時候,可採用微軟推薦的標準方法來進行檢查。

當然,這個方法只適用於運行期庫的標準堆,進程建立的私人堆不能用此方法來檢測,這種情況我們暫時不考慮。

先大概說一下微軟推薦的檢測方法。

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

#define _CRTDBG_MAP_ALLOC#include <stdlib.h>#include <crtdbg.h>

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

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

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

_CrtDumpMemoryLeaks();

這樣,在調試輸出區就能看到堆泄漏檢測的內容了,而且裡面還包含了原始碼資訊,極大的方便了調試工作。

微軟又提到:

如果程式總是在同一位置退出,調用 _CrtDumpMemoryLeaks 將非常容易。如果程式從多個位置退出,則無需在每個可能退出的位置放置對 _CrtDumpMemoryLeaks 的調用,而可以在程式開始處包含以下調用:

_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

這樣,只有在入口函數退出之後,運行期庫進行最後的清理工作結束之前,_CrtDumpMemoryLeaks才會被真正調用,你將有機會把自己建立的全域對象所佔用的記憶體釋放掉,避免這些記憶體被統計到未釋放的堆當中。


需要注意的是,前面的標頭檔包含應該被原始碼中的每個模組所引用,未引用的模組的堆資訊在輸出的時候將無法被識別,所以你最好將這個標頭檔包含放在類似afxstd.h的預包含檔案中,以保證所有模組都能引用到這組標頭檔資訊。


另外 ,可以把輸出資訊重新導向到比如磁碟的檔案中,方法是調用這個函數:_CrtSetReportMode。


現在再介紹在實際應用中發現的問題,上面的步驟可以解決你自己的程式的堆泄漏問題,但如果你的可執行程式引用了其他庫,靜態或者是動態,如果這些庫中也存在堆泄漏,那麼你是看不到原始碼資訊的,只能看到原始資訊!


下面只說靜態庫且有原始碼的情況,這時候,你可以在這個靜態庫的原始碼的每個模組中加入上面提到的語句:

#define _CRTDBG_MAP_ALLOC#include <stdlib.h>#include <crtdbg.h>


這樣,你在調試輸出中就能看到原始碼資訊了,至於動態庫的問題在後續中再分析。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.