青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

面對現實,超越自己
逆水行舟,不進則退
posts - 269,comments - 32,trackbacks - 0
之所以撰寫這篇文章是因為前段時間花費了很大的精力在已經成熟的代碼上再去處理memory leak問題。寫此的目的是希望我們應該養成良好的編碼習慣,盡可能的避免這樣的問題,因為當你對著一大片的代碼再去處理此類的問題,此時無疑增加了解決的成本和難度。準確的說屬于補救措施了。
1. 什么是內存泄漏(memory leak)?

 指由于疏忽或錯誤造成程序未能釋放已經不再使用的內存的情況。內存泄漏并非指內存在物理上的消失,而是應用程序分配某段內存后,由于設計錯誤,失去了對該段內存的控制,因而造成了內存的浪費。 

A memory leak is a particular type of unintentional memory consumption by a computer program where the program fails to release memory when no longer needed. This condition is normally the result of a bug in a program that prevents it from freeing up memory that it no longer needs.This term has the potential to be confusing, since memory is not physically lost from the computer. Rather, memory is allocated to a program, and that program subsequently loses the ability to access it due to program logic flaws. 

2. 對于C和C++這種沒有Garbage Collection 的語言來講,我們主要關注兩種類型的內存泄漏:

   堆內存泄漏(Heap leak)。對內存指的是程序運行中根據需要分配通過malloc,realloc new等從堆中分配的一塊內存,再是完成后必須通過調用對應的 free或者delete 刪掉。如果程序的設計的錯誤導致這部分內存沒有被釋放,那么此后這塊內存將不會被使用,就會產生Heap Leak. 

  系統資源泄露(Resource Leak).主要指程序使用系統分配的資源比如 Bitmap,handle ,SOCKET等沒有使用相應的函數釋放掉,導致系統資源的浪費,嚴重可導致系統效能降低,系統運行不穩定。  

3. 如何解決內存泄露?

內存泄露的問題其困難在于1.編譯器不能發現這些問題。2.運行時才能捕獲到這些錯誤,這些錯誤沒有明顯的癥狀,時隱時現。3.對于手機等終端開發用戶來說,尤為困難。下面從三個方面來解決內存泄露:

第一,良好的編碼習慣,盡量在涉及內存的程序段,檢測出內存泄露。當程式穩定之后,在來檢測內存泄露時,無疑增加了排除的困難和復雜度。

使用了內存分配的函數,要記得要使用其想用的函數釋放掉,一旦使用完畢。

Heap memory:

malloc\realloc ------  free

new \new[] ----------  delete \delete[]

GlobalAlloc------------GlobalFree 

要特別注意數組對象的內存泄漏

     MyPointEX *pointArray =new MyPointEX [100];

      其刪除形式為:

     delete []pointArray 

Resource Leak :對于系統資源使用之前要仔細看起使用方法,防止錯誤使用或者忘記釋放掉系統資源。

我們看MSDN上一個創建字體的例子:
示例代碼
如果使用完成時候忘記釋放字體,就造成了資源泄漏。 

   對于基于引用計數的系統對象尤其要注意,因為只有其引用計數為0時,該對象才能正確被刪除。而其使用過程中有其生成的新的系統資源,使用完畢后,如果沒有及時刪除,都會影響其引用計數。
示例代碼

DNS_Release(pMe->m_pDns);//當程序運行到此時,其返回值不是0,是1,其含義是程序已經產生內存泄露了,系統已經有一個由DNS所產生的內核對象沒有釋放,而當這段代碼多次執行之后,內存泄露將不斷增加……..

m_pDns=NULL;

  }

看起來很不直觀,仔細分析就會發現,對象pDnsResponse是從m_pDns產生新的object,所以m_pDns的引用計數會增加,因此在使用完pDnsResponse,應該release 該對象使其引用計數恢復正常。
 
對于資源,也可使用RAII,RAII(Resource acquisition is initialization)資源獲取即初始化,它是一項很簡單的技術,利用C++對象生命周期的概念來控制程序的資源,例如內存,文件句柄,網絡連接以及審計追蹤(audit trail)等.RAII的基本技術原理很簡單.若希望保持對某個重要資源的跟蹤,那么創建一個對象,并將資源的生命周期和對象的生命周期相關聯.如此一來,就可以利用C++復雜老練的對象管理設施來管理資源.(有待完善) 

例2: 

Struct ITypeface *pTypeface;

if (pTypeface)

{

IANY_CreateInstance(g_pApplet->m_pIShell,AEECLSID_BTFETypeface,void**)& Typeface);

} 

接下來我們就可以從這個接口上面創建字體,比如

IHFont **pihf=NULL;

   ITypeface_NewFontFromFile(ITypeface,……,&pihf).

   ITypeface_NewFontFrommemory(ITypeface,……..,&pihf)

   ITypeface_NewFontFromClassID(IType,……,&pihf)

 

   但是要切記,這些字體在使用完成后一定要release掉,否則最后 iTypeface的引用計數就是你最后沒有刪除掉的字體的個數。 

第二,重載  new 和 delete。這也是大家編碼過程中常常使用的方法。

下面給出簡單的sample來說明。
示例代碼

其主要思路是將分配的內存以鏈表的形式自行管理,使用完畢之后從鏈表中刪除,程序結束時可檢查改鏈表,其中記錄了內存泄露的文件,所在文件的行數以及泄露的大小哦。
第三,Boost 中的smart pointer(待完善,結合大家的建議)
第四,一些常見的工具插件,詳見我的Blog中相關文章。

4. 由內存泄露引出內存溢出話題:

所謂內存溢出就是你要求分配的內存超出了系統能給你的,系統不能滿足需求,于是會產生內存溢出的問題。

常見的溢出主要有:

內存分配未成功,卻使用了它。 常用解決辦法是,在使用內存之前檢查指針是否為NULL。如果指針p 是函數的參數,那么在函數的入口處用assert(p!=NULL)進行檢查。如果是用malloc 或new 來申請內存,應該用if(p==NULL)或if(p!=NULL)進行防錯處理。

內存分配雖然成功,但是尚未初始化就引用它。 內存分配成功并且已經初始化,但操作越過了內存的邊界。 例如在使用數組時經常發生下標“多1”或者“少1”的操作。特別是在for 循環語句中,循環次數很容易搞錯,導致數組操作越界。

使用free 或delete 釋放了內存后,沒有將指針設置為NULL。導致產生“野指針”。

程序中的對象調用關系過于復雜,實在難以搞清楚某個對象究竟是否已經釋放了內存,此時應該重新設計數據結構,從根本上解決對象管理的混亂局面。(這點可是深有感受,呵呵)

 不要忘記為數組和動態內存賦初值。防止將未被初始化的內存作為右值使用。

windows如何下防止內存泄露

windows下開發C++程序的時候,我們經常需要用到malloc開申請內存,然后利用free回收內存,但是開發人員的不小心可能會忘記free掉內存,這樣就導致了內存泄露

利用庫檢測內存泄露信息

#define _CRTDBG_MAP_ALLOC  //如果沒有這個宏定義,我們只能知道有內存泄露,卻無法知道在哪個地方申請內存忘記了釋放

#include
<stdlib.h>
#include
<crtdbg.h>
int main(void)
{
    
char *= (char *)malloc(sizeof(char* 100);
    _CrtDumpMemoryLeaks();
}
使用crtdbg來檢測到內存泄露很簡單,只要在文件的第一行定義_CRTDBG_MAP_ALLOC,然后include頭文件crtdbg.h,在程序需要內存檢測的地方調用_CrtDumpMemoryLeaks,就可以輸出內存泄露的信息,如上面的程序,我們申請了100個字節的內存而沒有釋放,但是我們可以很清楚地看到內存泄露在 哪個地方。

 

我們在main.cpp這個文件中的第八行申請了內存,但是沒有進行釋放

那么編譯器是怎么知道我們有內存泄露呢??就是利用宏定義把我們的調用的malloc替換成crtdbg 庫里面的_malloc_dbg,我們在申請內存的時候,_malloc_dbg會先記錄下我們申請內存的行數以及大小(記得編譯器有內置的宏定義__LINE____FILE__?),把這些信息放到一個list(只是舉例,使用list保存這些信息一旦程序大了會很慢)里面,當我們free內存的時候,把這塊內存的信息從list里面刪除掉,我們調用_CrtDumpMemoryLeaks()的時候就是在把這個list的信息依次打印出來而已

下面是我們定義_CRTDBG_MAP_ALLOC后實際上所調用的malloc原型,malloc已經成了一個宏定義

#define   malloc(s)             _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)

當然,我們一般調用_CrtDumpMemoryLeaks的時候都是在程序的結尾處,如果我們的程序有多個出口,我們值需要在程序開始處調用_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ) 就可以了

有時候我們需要檢測某一段代碼是否有內存泄露,crtdbg庫也可以幫我們做到

_CrtMemState s1;
_CrtMemState s2;  
_CrtMemCheckpoint(
&s1); 
char *p2 = (char *)malloc(400);
_CrtMemCheckpoint(
&s2);
_CrtMemState s3;
if (_CrtMemDifference(&s3,&s1,&s2))
{
     _CrtMemDumpStatistics(
&s3);
}

 

這樣,我們在輸出窗口將會看到s1s2之間的內存使用信息:

0 bytes in 0 Free Blocks. 400 bytes in 1 Normal Blocks. 0 bytes in 0 CRT Blocks. 0 bytes in 0 Ignore Blocks. 0 bytes in 0 Client Blocks. Largest number used: 0 bytes. Total allocations: 400 bytes.

crtdbg庫也有缺點,當你使用一個別人提供的lib或者dll庫的時候,你調用這個函數,這個函數分配了內存,需要你去調用另外一個函數才能把內存釋放掉,但是你不知道這個函數需要調用另外一個函數才能釋放掉內存,這個是無法通過crtdbg庫檢測出來的,這個函數包括c++new函數,所以這個庫實際上不適用C++

利用share_ptr來管理內存

如果有使用過boost庫的應該知道,boost里面有一個shart_ptr被譽為神器,因為他可以幫我們自動管理內存,具體用法很簡單:

  boost::shared_ptr < connection > p ( new connection());

這樣的話我們不需要去delete內存,shartd_ptr會在我們不需要這快內存的時候幫我們delete掉,shartd_ptr內部是使用引用計數以及C++RAII,有別的對象引用該指針的時候引用技術就+1shartd_ptr析構函數調用的時候引用計數就-1,當為0的時候就delete掉該指針,所以我們并不需要調用delete來釋放資源,share_ptr會幫我們管理

shared_ptr雖然看起來很好用,但是當程序一旦復雜起來,shared_ptr依然也會變復雜(shared_ptr四宗罪),當然boost本身就比較復雜,這個也是我比較不喜歡boost的一個原因

將資源集中管理

這個也是我比較經常使用的方法,特別是在大程序的使用,配合單件模式,將資源在整個程序或者模塊中集中管理,這樣在程序結束的時候只要我們在析構函數里面有清理這些資源,我們就可以避免內存泄露,對于數據的一些寫操作全部在這個類中統一操作,如果要暴露內部的數據,只對外提供const數據(可以通過強轉去掉const屬性)

當然這個方法并不適用于所有場景,比如我們需要提供庫給別人,我們沒辦法預測到客戶需要什么操作,所以這個方法只適用內部團隊開發

總之內存管理據我所知到現在還是沒有什么好的解決方法,特別是當代碼一旦膨脹的時候,到現在好像java,pythonerlang都有內存泄露的問題,我們只能在平常開發中多注意了

參考資料:

陳碩的博客(有一些shared_ptr的資料,也可以從這里看出shared_ptr使用起來沒那么簡單)
shared_ptr四宗罪
MSDN crtdbg庫

本文相關鏈接:http://blog.csdn.net/na_he/article/details/7429171
                http://www.cnblogs.com/linyilong3/archive/2013/03/23/2977247.html

posted on 2013-05-02 18:29 王海光 閱讀(7197) 評論(0)  編輯 收藏 引用 所屬分類: C++
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美激情1区2区| 亚洲一区黄色| 欧美国产一区二区| 久久一区二区三区四区| 久久女同精品一区二区| 欧美人成在线视频| 国产欧美一区视频| 欧美一级理论片| 国产欧美日韩一区二区三区在线| 欧美人与禽性xxxxx杂性| 国产女主播视频一区二区| 亚洲激情在线视频| 亚洲理论电影网| 亚洲国产激情| 久久成人在线| 亚洲精品在线免费| 国产精品久久二区二区| 久久久美女艺术照精彩视频福利播放| 久久免费午夜影院| 亚洲精品乱码久久久久久蜜桃麻豆| 亚洲无线一线二线三线区别av| 国产嫩草一区二区三区在线观看| 日韩写真视频在线观看| 久久久国产午夜精品| 欧美人牲a欧美精品| 国产色产综合产在线视频| 亚洲一区二区三区乱码aⅴ蜜桃女| 久久精品国产久精国产一老狼| 亚洲精品一区二区三| 欧美成人国产| 欧美一区二区日韩一区二区| 亚洲专区一区| 久久久久久高潮国产精品视| 麻豆久久婷婷| 欧美性大战久久久久久久| 永久久久久久| 欧美jjzz| 欧美aa在线视频| 亚洲香蕉在线观看| 国产精品99免视看9| 在线观看成人网| 先锋亚洲精品| 久久国产一二区| 亚洲综合三区| 亚洲激情婷婷| 免费成人小视频| 亚洲精品国精品久久99热| 久久久久国产一区二区三区| 亚洲国产精品一区二区久 | 亚洲三级国产| 久久午夜电影| 国产麻豆精品久久一二三| 欧美伊人久久久久久久久影院 | 日韩一区二区精品葵司在线| 欧美伊人久久久久久午夜久久久久| 久久午夜电影| 欧美亚日韩国产aⅴ精品中极品| 香蕉久久夜色| 免费观看成人www动漫视频| 亚洲神马久久| 欧美激情视频给我| 麻豆免费精品视频| 蜜桃av综合| 一本色道久久88综合日韩精品| 亚洲一区二区三区视频| 欧美日韩一区在线播放| 亚洲女同在线| 欧美在线视频免费观看| 亚洲第一精品久久忘忧草社区| 久久久久久久久综合| 午夜在线播放视频欧美| 国产一区香蕉久久| 在线观看日韩av| 国产精品久久激情| 国产精品高清在线| 欧美精品日韩一区| 欧美另类一区二区三区| 久久性色av| 亚洲午夜激情在线| 亚洲欧美精品| 亚洲与欧洲av电影| 亚洲欧美日韩综合aⅴ视频| 一本色道久久综合亚洲精品不卡 | 国产精品腿扒开做爽爽爽挤奶网站| 欧美大色视频| 蜜臀av在线播放一区二区三区| 一区二区三区毛片| 99成人免费视频| 一本一本久久a久久精品综合妖精 一本一本久久a久久精品综合麻豆 | 亚洲视频一区二区免费在线观看| 欧美中文字幕在线| 国产日韩av在线播放| 久久国产一区| 性欧美大战久久久久久久久| 欧美精品午夜| 欧美大片在线看| 一本久久知道综合久久| 久久五月婷婷丁香社区| 亚洲三级影院| 久久国内精品自在自线400部| 99国产精品久久久久老师| 正在播放欧美一区| 国产精品99久久久久久久女警 | 欧美日韩国产精品一区| 一区二区三区偷拍| 亚洲欧美成aⅴ人在线观看| 亚洲主播在线观看| 亚洲午夜激情| 久久久久久久激情视频| 免费在线看一区| 久久亚洲综合网| 欧美日韩成人综合| 国产日韩av在线播放| 国产日韩欧美中文| 最新亚洲激情| 亚洲图片你懂的| 久久精品视频99| 欧美成人自拍视频| 一区二区三区|亚洲午夜| 亚洲欧美韩国| 欧美~级网站不卡| 国产精品男gay被猛男狂揉视频| 国产夜色精品一区二区av| 亚洲国产精品久久91精品| 91久久中文| 性久久久久久久久久久久| 男同欧美伦乱| 亚洲成人在线免费| 久久人91精品久久久久久不卡 | 亚洲美女av网站| 欧美激情国产精品| 欧美成人亚洲成人| 亚洲欧洲精品一区| 在线一区日本视频| 欧美怡红院视频一区二区三区| 久久香蕉国产线看观看av| 亚洲福利视频一区二区| 一区二区三区日韩欧美精品| 欧美一区二区三区日韩视频| 乱中年女人伦av一区二区| 欧美日韩在线播放| 精品av久久久久电影| 国产日韩欧美精品一区| 亚洲精品国产精品国自产在线 | 国产女同一区二区| 亚洲激情不卡| 欧美专区18| 亚洲人成网站777色婷婷| 欧美伊人精品成人久久综合97 | 亚洲视频一区二区免费在线观看| 亚洲精品网站在线播放gif| 久久精品一区二区三区中文字幕| 亚洲高清网站| 蜜臀av性久久久久蜜臀aⅴ四虎| 国产精品自在线| 日韩亚洲欧美成人一区| 欧美成人性网| 欧美在线视频观看| 国产精品视频| 99热在这里有精品免费| 免费试看一区| 性欧美18~19sex高清播放| 中文在线资源观看网站视频免费不卡| 夜夜爽99久久国产综合精品女不卡 | 亚洲图片激情小说| 亚洲成人资源网| 欧美影院成人| 国产精品久久中文| 国产综合久久| av成人福利| 久久久国产精品一区二区三区| 亚洲国产精品久久久| 亚洲影视中文字幕| 奶水喷射视频一区| 国产欧美在线播放| 日韩亚洲国产欧美| 欧美一区综合| 久久久久久电影| 国产精品久久久久9999吃药| 欧美一区二区三区在线看| 欧美一级视频精品观看| 午夜精品成人在线| 午夜视频一区| 蜜桃av一区| 国产精品电影在线观看| 国产欧美一区二区精品仙草咪 | 国产精品捆绑调教| 在线中文字幕一区| 欧美国产日韩一区二区| 久久国产主播| 狠狠色丁香婷婷综合| 久久尤物视频| 久久久久久久综合| 国产亚洲人成a一在线v站| 亚洲一区二区三区免费在线观看| 日韩亚洲欧美成人一区| 欧美午夜美女看片| 欧美中文字幕在线视频| 久久高清国产| 亚洲高清不卡在线|