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

面對現實,超越自己
逆水行舟,不進則退
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,有別的對象引用該指針的時候引用技術就+1,shartd_ptr析構函數調用的時候引用計數就-1,當為0的時候就delete掉該指針,所以我們并不需要調用delete來釋放資源,share_ptr會幫我們管理

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

將資源集中管理

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

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

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

參考資料:

陳碩的博客(有一些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>
            亚洲尤物视频在线| 在线一区观看| 91久久久久久久久| 午夜电影亚洲| 亚洲电影免费观看高清完整版| 在线观看一区二区精品视频| 一区二区日韩免费看| 欧美凹凸一区二区三区视频| 亚洲综合精品自拍| 欧美日韩国产精品专区| 在线日韩av| 久久免费高清视频| 欧美一区午夜精品| 国产精品婷婷午夜在线观看| 亚洲天堂男人| 99re6这里只有精品| 欧美久久久久| 一本色道久久综合亚洲91| 亚洲国产经典视频| 欧美不卡激情三级在线观看| 91久久国产综合久久| 欧美激情中文字幕一区二区| 久久久久久久91| 亚洲第一精品福利| 欧美高清视频一二三区| 麻豆91精品| 日韩视频不卡| 野花国产精品入口| 国产精品一卡| 免费在线亚洲| 欧美精品日日鲁夜夜添| 中日韩美女免费视频网址在线观看| 亚洲精品一区二区三区不| 欧美视频在线观看 亚洲欧| 欧美亚洲综合网| 久久亚洲精品视频| 一本一道久久综合狠狠老精东影业 | 日韩西西人体444www| 欧美三区在线| 久久九九免费视频| 麻豆国产精品一区二区三区| 99亚洲一区二区| 午夜精品一区二区在线观看 | 国产麻豆精品视频| 久久在线91| 欧美黄在线观看| 亚洲永久在线观看| 久久成人免费网| 日韩午夜高潮| 午夜精品99久久免费| 精品二区久久| 一区二区三区视频在线看| 国产亚洲福利社区一区| 亚洲高清在线视频| 国产精品一区亚洲| 欧美激情影院| 国产麻豆精品theporn| 欧美激情第一页xxx| 国产精品国产三级国产专播精品人 | 国产精品v日韩精品v欧美精品网站| 小嫩嫩精品导航| 美女精品国产| 午夜精品久久久久久久99水蜜桃| 久久久999精品| 亚洲欧美国产精品va在线观看 | 亚洲欧美日韩国产成人| 久久久噜噜噜久久久| 亚洲影院在线观看| 久久一区二区三区国产精品| 亚洲小说春色综合另类电影| 久久全球大尺度高清视频| 亚洲欧美日韩综合| 欧美精品乱人伦久久久久久 | 亚洲视屏在线播放| 亚洲精品国偷自产在线99热| 欧美一级大片在线观看| 亚洲一区二区免费视频| 免费一级欧美在线大片| 久久日韩精品| 国产欧美日韩麻豆91| 一本久久知道综合久久| 亚洲精品乱码久久久久久日本蜜臀| 欧美一区二区啪啪| 欧美亚洲自偷自偷| 国产精品乱码一区二区三区| 亚洲国产成人久久综合| 尤物yw午夜国产精品视频| 午夜精品久久久久久久男人的天堂 | 一区二区精品在线观看| 另类酷文…触手系列精品集v1小说| 久久久福利视频| 国产色产综合产在线视频| 亚洲一区bb| 亚洲欧美成人网| 国产精品黄色| 亚洲午夜影视影院在线观看| 亚洲尤物视频网| 国产情侣久久| 欧美一区日韩一区| 久热国产精品| 91久久精品国产91性色tv| 久久蜜桃资源一区二区老牛| 午夜亚洲视频| 国产日韩欧美一区二区三区在线观看 | 久久久久久久久久久久久女国产乱 | 夜夜嗨av色一区二区不卡| 蜜桃精品久久久久久久免费影院| 久久久久久999| 亚洲一区激情| 欧美一区亚洲二区| 国产精品久久久久久久久搜平片| 亚洲国产欧美久久| aa级大片欧美| 国产精品久久久91| 亚洲午夜三级在线| 欧美在线亚洲| 狠狠色丁香久久婷婷综合丁香| 欧美一区二区在线播放| 另类亚洲自拍| 亚洲精品乱码久久久久久蜜桃麻豆 | 美女日韩欧美| 亚洲欧洲精品天堂一级| 亚洲图片欧美一区| 国产欧美日韩精品在线| 久久国产精品亚洲va麻豆| 欧美.日韩.国产.一区.二区| 亚洲精品一线二线三线无人区| 欧美精品色综合| 亚洲综合清纯丝袜自拍| 免费在线观看一区二区| 亚洲深夜福利| 国产中文一区二区| 欧美精品videossex性护士| 亚洲香蕉网站| 欧美成人一区二区三区片免费| 一区二区欧美在线| 国产有码在线一区二区视频| 欧美黄色一区二区| 欧美一区永久视频免费观看| 欧美激情第三页| 久久精品国产欧美激情| 亚洲免费大片| 国内精品久久久久伊人av| 欧美美女喷水视频| 久久久久久亚洲综合影院红桃| 亚洲精品在线免费观看视频| 久久久久久久网站| 亚洲影院色在线观看免费| 亚洲啪啪91| 激情视频一区| 国产日韩欧美综合一区| 欧美日韩美女一区二区| 你懂的国产精品| 久久国产精品亚洲va麻豆| 亚洲午夜av在线| 亚洲欧洲日本专区| 欧美a级一区| 久久综合图片| 久久精品国产亚洲a| 亚洲一区二区在线观看视频| 亚洲精品国产拍免费91在线| 伊人久久亚洲热| 国内精品久久久久国产盗摄免费观看完整版 | 亚洲一二三四区| 亚洲片在线观看| 免费久久久一本精品久久区| 午夜久久美女| 亚洲欧美中文字幕| 亚洲图片在线观看| 一区二区三区精密机械公司| 亚洲欧洲一区二区三区| 久久字幕精品一区| 久久精品国产一区二区电影| 亚洲男人影院| 午夜精品一区二区三区在线视 | 亚洲美女av电影| 欧美激情精品久久久| 欧美在线亚洲综合一区| 性欧美超级视频| 久久国产精品99久久久久久老狼 | 免费一区二区三区| 久久在线观看视频| 女生裸体视频一区二区三区| 欧美99在线视频观看| 亚洲福利视频免费观看| 亚洲国产精品成人综合色在线婷婷| 欧美国产一区视频在线观看 | 欧美高清在线观看| 女同一区二区| 欧美高潮视频| 欧美另类在线观看| 欧美日韩美女一区二区| 欧美偷拍一区二区| 国产精品免费视频xxxx| 国产精品自拍网站| 国语自产在线不卡| 尤妮丝一区二区裸体视频| 亚洲国产精品久久人人爱蜜臀 | 欧美日韩亚洲视频| 国产精品欧美久久久久无广告|