內存泄漏:linux
程序申請了堆空間,但是「忘記」釋放,致使該塊區域在程序結束前沒法被再次使用致使的。泄漏時間長了,就會致使用戶空間內存不足,嚴重的致使死機。api
假設泄漏比較嚴重,很是easy察覺;但是有些泄漏很是緩慢,不easy察覺,但是軟件會執行很是長時間後,會慢慢致使嚴重問題,而且當發現症狀的時候,基本上已是比較晚的時候了,想要識別泄漏,仍是可以實現的,本篇文章來聊聊內存操做的原理。app
C++中申請內存使用的是new,C語言中使用的malloc(還有其它比方alloc原理相似),普通狀況下new調用的是C語言使用的malloc。而由於C++/C可以在多個操做系統使用,因此可以想到malloc確定是封裝了不一樣操做系統提供的API,比方Windows上邊調用的有這幾個:VirtualAlloc、VirtualAllocEx、VirtualFree、VirtualProtect、VirtualQuery、VirtualLock、VirtualUnLock,只是它們分配的都是內存頁的整數倍的虛擬內存空間RAM,然而咱們想要使用內存的時候,差點兒很是少需要整數倍,那麼就需要封裝它們改變靈活一些,API替咱們封裝了:HeapAlloc、GlobalAlloc,它們全都是內核級別,存在於kernel32.dll裏邊。spa
很是easy看出,咱們調用new,實際調用的是HeapAlloc,只是不需要在檢測內存泄漏的時候走到這麼底層,迴歸正傳,仍是回到new/malloc。操作系統
在申請內存的時候new調用malloc,釋放delete調用free,那麼怎麼可讓每一次申請和每一次釋放均可以記錄,終於找到可能的哪怕1字節的泄漏呢?easy想到,在new調用malloc的時候,記錄下申請空間的地址,在delete調用free的時候,將記錄裏邊相應地址的數據刪除,這樣最後假設記錄中還有剩餘記錄,則表示有泄漏。這樣還不夠,即便知道泄漏,可是不知道在哪有有什麼用呢?顯然在記錄的時候,除了記錄地址,還應記錄申請的文件名稱字、行數,這樣最後有泄漏的時候,能夠立馬知道在哪裏泄漏,原理就是這些,看下樣例、解決的基礎代碼。.net
#include #include using namespace std; #include void* operator new(size_t size, const char* file, int line) { void *p = (void*)malloc(size); printf("【%d】%s : (%d) 申請%d字節內存\n", p,file,line,size); return p; } void* operator new[](size_t size, const char* file, int line) { return operator new(size, file, line); } #define new DEBUG_NEW #define DEBUG_NEW new(__FILE__, __LINE__) void operator delete(void* pointer) { printf("【%d】釋放內存\n",pointer); free(pointer); } void operator delete[](void* pointer) { operator delete(pointer); } void operator delete(void* pointer, const char* file, int line) { operator delete(pointer); } void operator delete[](void* pointer, const char* file, int line) { operator delete(pointer, file, line); } int main() { int *pos1 = new int[10]; int *pos2 = new int(0x70000001); delete []pos1; delete pos2;; return 0; }這裏邊沒有記錄申請堆的文件名稱字、行號,只是添加很是easy,用個 HASH 保存便可了,就不改動了。執行結果:
easy發現申請和釋放是成對的,釋放內存地方原本也可以知道釋放的大小的,只是有點忘記詳細保存的方式了,C++編譯器通常都會在new返回的僅僅針的前邊幾字節記錄申請的長度等信息,可以在上邊代碼這麼改動:
code
就會出現崩潰,因爲將編譯器的數據改動了,它沒法正常釋放內存了。blog
有個比較不錯的開源內存泄漏檢測項目:Visual Leak Detector,用它很方便,只需要將它的頭文件、靜態連接庫加入到咱們的項目中就能夠,用上邊的樣例作樣例:ip
而當去掉一個delete 的時候,是這種:
內存
直接找到泄漏大小、地點。
Visual Leak Detector下載地址:
參考:
http://www.ibm.com/developerworks/cn/linux/l-mleak2/
http://blog.csdn.net/yapingxin/article/details/6751940
http://bbs.csdn.net/topics/20329607
http://blog.csdn.net/g5dsk/article/details/6077601
http://babybandf.blog.163.com/blog/static/6199353201128101029894/
http://www.codeproject.com/KB/applications/visualleakdetector/vld-10.zip