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

隨筆-4  評論-40  文章-117  trackbacks-0

c++內存分配優先使用內存池,而不是newdelete

轉載

原文出處:http://www.devdiv.net/home/space.php?uid=125&do=blog&id=364

 

認識一下newdelete的開銷:

newdelete首先會轉調用到mallocfree,這個大家應該很熟識了。很多人認為malloc是一個很簡單的操作,其實巨復雜,它會執行一個系統調用,從用戶態轉到內核態,該系統調用會鎖住內存硬件,然后通過鏈表的方式查找空閑內存,如果找到大小合適的,就把用戶的進程地址映射到內存硬件地址中,然后釋放鎖,返回用戶態。delete是一個反過程。

相對的,如果不是使用堆分配,而是直接在棧上分配,比如類型int,那么開銷就是把sp這個寄存器加上sizeof(int)

內存池模式:

       內存池就是預先分配好,放到進程空間的內存塊,用戶申請與釋放內存其實都是在進程內進行,SGI-STLalloc遇到小對象時就是基于內存池的。只有當內存池空間不夠時,才會再從系統找一塊很大的內存。

       內存池模式是如此之重要,以至于讓我想不明白為什么四人幫那本《設計模式》沒有把內存池列為基本模式,目前其它的教材,包括學院教材,實踐教材都沒有列出這個模式(講線程池模式的教材倒非常多)。可能他們認為這不屬于設計,而屬于具體實現吧。但我覺得這樣的后果是間接把很多c++ fans帶向低效的編碼方式。

sun公司就挺喜歡搞一些算法,用c++實現與java實現一遍,結果顯示c++的效率有時甚至比java低,很多c++高手看了之后都會覺得很難解,其實有玄機:javanew其實是基于內存池的,而c++new是直接系統調用。

c++內存池模式的發展:

       c++98標準之前,基本上大多數程序員沒用使用內存池,c++98 標準之后,內存池的使用也只是停留在STL內部的使用上,并沒有得到推廣。

       其實我認為,STL的內存分配模式是一場變革,它不但包含內存分配的革命,也包含了內存管理(這個話題先放一邊)的革命,只是這場變革被很多人忽略了。也有一些人認為STL的內存分配方案有潛在問題,就是只管從系統分配,但卻永遠不會調用系統級的釋放,如果使用不當,程序拿住的內存會越來越多。我自己工作過的項目沒遇上過這樣的問題,但之前營帳報表組的一個容災項目倒是遇上了。不過STL的內存模式沒有推廣最大的原因還是因為alloc不是標準組件,以至于被人忽略了。

       STL之后,一些c++ fans們開始搞出了幾套內部使用的內存池。為了項目需要,我自己也曾經做過一個。但這些都沒有很正式的公開,而且也不完美。

       大概在200x(-_-!),主導c++標準的一群牛人發起了一個叫boost的項目,才正式的把內存池帶到實用與標準化階段。

插入一點題外話:關于boost,很多人(包括我自己也曾經)產生誤解,認為它是準標準庫,是下一代標準庫。其實boost是套基礎建設,用來證明哪些方案是可行,哪些是不可行的,它里面的一些組件有可能會出局,也有可能不是以庫的方式存在,而是以語言核心的方式存在,下一代標準庫名字叫TR1,再一下代叫TR2(我對使用TR這個名字很費解,為什么不統一叫STL)

new,delete調用與內存池調用的效率對比:

講了這么多費話,要到關鍵時候了,用事例來證明為什么要優先使用內存池。下面這段代碼是我很久以前的一段測試案例,細節上可能有點懂難,但流程還是清晰的:

#include <time.h>

#include <boost/pool/object_pool.hpp>

 

struct CCC

{

    CCC() {}

    char data[10];

};

 

struct SSS

{

    SSS() {}

    short data[10];

};

 

struct DDD

{

    DDD() {}

    double data[10];

};

 

// new,delete封裝為一個與boost::object_pool一樣的接口,以便于測試

template <typename element_type, typename user_allocator = boost::default_user_allocator_malloc_free>

class new_delete_alloc

{

public:

    element_type* construct() { return new element_type; }

    void destroy(element_type* const chunk) { delete chunk; }

};

 

template

    template<typename, typename>

    class allocator

double test_allocator()

{

    // 使用了一些不規則的分配與釋放,增加內存管理的負擔

    // 但總體流程還是很規則的,基本上不產生內存碎片,要不然反差效果會更大。

 

    allocator<CCC> c_allc;

    allocator<SSS> s_allc;

    allocator<DDD> d_allc;

 

    double re = 0; // 隨便作一些運算,仿止編譯器優化掉內存分配的代碼

 

    for (unsigned int i = 0; i < 10000; ++i)

    {

        for (unsigned int j = 0; j < 10000; ++j)

        {

            CCC* pc = c_allc.construct();

            SSS* ps = s_allc.construct();

 

            re += pc->data[2];

            c_allc.destroy(pc);

 

            DDD* pd = d_allc.construct();

 

            re += ps->data[2];

            re += pd->data[2];

            s_allc.destroy(ps);

            d_allc.destroy(pd);

        }

    }

 

    return re;

}

 

int main(int argc, char* argv[])

{

    double re1 = 0;

    double re2 = 0;

 

    // 運行內存池測試時,基本上對我機器其它進程沒什么影響

    time_t begin = time(0);

    re1 = test_allocator<boost::object_pool>(); // 使用內存池boost::object_pool

    time_t seporator = time(0);

 

   

    // 運行到系統調用測試時,感覺機器明顯變慢,

    // 如果再加上內存碎片的考慮,對其它進程的影響會更大。

    std::cout << long(seporator - begin) << std::endl;

    re2 = test_allocator<new_delete_alloc>();           // 直接系統調用

    std::cout << long(time(0) - seporator) << std::endl;

 

    std::cout << re1 << re2 << std::endl;

}

總結:

在一個100000000次的循環中,使用內存池是3秒,使用系統調用是93秒。

可能會有人覺得100000000這個數很大,93秒沒什么,但想一下,一個表有幾千萬行是很正常的,如果每行有十多列,每列有數據類型,數據長度,數據內容。如果在這樣的一個循環錯誤的使用了newdelete

而且以上測試還沒有考慮到碎片的影響,以及運行該程序時對其它程序的影響。而且還有一點,就是機器的內存硬件容量越大,內存分配時,需要搜索的時間就可能越長,如果內存是多條共同工作的,影響就再進一步。

什么算是錯誤的使用呢,比如返回一個std::string給用戶,有人覺得new出來返回指針給用戶會更好,你可能會想到如果new的話,只產生一次string的構造,如果直接返回對象可能需要多次構造,所以new效率更高。但事實不是這樣,雖然在構造里會有字符串的分配,但其實這個分配是在內存池中進行的,而你直接的那個new就肯定是系統調用。

當然,有些情況是不可說用什么就用什么的,但如果可選的話,優先使用棧上的對象,其次考慮內存池,然后再考慮系統調用。



posted on 2009-08-26 10:46 李陽 閱讀(1182) 評論(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>
            久久岛国电影| 欧美高清成人| 欧美在线日韩| 欧美日韩国产综合视频在线| 国产在线视频不卡二| 午夜精品视频网站| 日韩午夜视频在线观看| 欧美a级大片| 亚洲成人中文| 蜜桃av一区二区在线观看| 亚洲欧美一级二级三级| 国产精品h在线观看| 中文日韩在线| 99国产一区二区三精品乱码| 欧美成人免费网| 亚洲日韩第九十九页| 亚洲国产精品精华液网站| 欧美影片第一页| 国内精品模特av私拍在线观看 | 久久久综合网站| 亚洲视频中文字幕| 国产精品久久久久久久久久免费| 一本久道久久久| 99精品黄色片免费大全| 欧美亚一区二区| 欧美伊久线香蕉线新在线| 一区视频在线| 亚洲天堂成人| 欧美日韩综合在线| 亚洲一区二区在线视频| 亚洲在线观看免费| 激情亚洲成人| 亚洲国产精品免费| 欧美午夜久久| 久久av老司机精品网站导航| 久久精品国产第一区二区三区| 伊人久久婷婷色综合98网| 亚洲国产精品视频| 国产精品入口麻豆原神| 久久九九精品99国产精品| 久热成人在线视频| 亚洲五月婷婷| 久久久久久一区二区| 99精品免费网| 久久国产精品网站| 亚洲精品五月天| 亚洲女性喷水在线观看一区| 国内一区二区在线视频观看| 亚洲欧洲日本在线| 国产精品最新自拍| 欧美激情按摩在线| 国产美女精品| 亚洲国产高清一区二区三区| 国产精品久久久久国产a级| 老司机凹凸av亚洲导航| 欧美性猛交一区二区三区精品| 久久一区中文字幕| 国产精品久久久久一区二区| 老司机免费视频久久| 欧美视频中文字幕| 欧美岛国激情| 国产亚洲精品一区二区| 日韩视频不卡中文| 在线成人免费视频| 午夜精品短视频| 99精品久久| 欧美~级网站不卡| 欧美亚洲视频| 欧美精品日韩一区| 欧美电影在线观看完整版| 国产精品一区二区久久| 亚洲精品中文字幕在线| 亚洲国产精品va| 欧美伊人久久久久久久久影院 | 亚洲一区二区成人在线观看| 久久偷窥视频| 久久久噜噜噜久久狠狠50岁| 国产精品免费看片| 99精品热视频只有精品10| 亚洲精品一区二区在线| 久久久精品一区| 久久狠狠一本精品综合网| 国产精品白丝黑袜喷水久久久| 亚洲黄色小视频| 亚洲二区在线观看| 久久精品亚洲一区二区三区浴池| 欧美与黑人午夜性猛交久久久| 欧美午夜精品久久久久久孕妇 | 久久一区二区三区国产精品 | 午夜精品久久久久久久男人的天堂| 噜噜噜躁狠狠躁狠狠精品视频| 久久精品一区二区三区中文字幕| 国产精品国产精品| 日韩一二三区视频| 亚洲天堂网在线观看| 欧美三级小说| 亚洲午夜91| 性做久久久久久| 国产婷婷一区二区| 久久久久久91香蕉国产| 免费观看欧美在线视频的网站| 狠狠v欧美v日韩v亚洲ⅴ| 久久动漫亚洲| 欧美mv日韩mv亚洲| 亚洲黑丝在线| 欧美激情国产日韩| 99re在线精品| 亚洲资源av| 国产一区999| 老司机精品福利视频| 亚洲三级毛片| 一区二区三区欧美成人| 欧美午夜一区二区福利视频| 午夜精品久久久久久久男人的天堂| 欧美主播一区二区三区美女 久久精品人 | 国产精品啊啊啊| 亚洲欧美日韩精品久久奇米色影视| 欧美一区二区视频免费观看| 韩国av一区二区三区四区| 蜜桃av一区二区| 99精品国产热久久91蜜凸| 性色一区二区| 亚洲激情一区二区| 国产精品久久久久9999高清| 香蕉久久一区二区不卡无毒影院| 久久天堂国产精品| 亚洲精品一区久久久久久| 欧美日韩综合不卡| 亚洲欧美久久| 亚洲高清三级视频| 欧美一级欧美一级在线播放| 亚洲国产另类久久精品| 国产精品二区二区三区| 久久久精品五月天| 一个色综合av| 欧美国产精品一区| 午夜精品久久| 亚洲精品一区在线观看| 国产欧美在线观看| 免费日韩av电影| 性亚洲最疯狂xxxx高清| 亚洲精品视频在线观看网站| 欧美亚洲视频在线观看| 亚洲伦理一区| 狠狠色综合日日| 国产精品国产一区二区| 免费人成网站在线观看欧美高清 | 欧美系列亚洲系列| 久久夜色精品| 亚洲性人人天天夜夜摸| 欲香欲色天天天综合和网| 欧美视频导航| 欧美成人免费视频| 欧美一区二区三区四区夜夜大片| 欧美大片va欧美在线播放| 欧美在线观看一二区| 一区二区三区四区五区在线| 亚洲第一网站| 国产欧美日韩伦理| 国产精品国产精品| 欧美日韩不卡一区| 欧美www视频| 久久久青草婷婷精品综合日韩| 中文av字幕一区| 99亚洲一区二区| 亚洲人永久免费| 亚洲黄色天堂| 欧美激情精品久久久久久黑人| 久久久久久久一区二区| 性欧美videos另类喷潮| 亚洲在线观看免费| 亚洲一区二区三区在线看| 一区二区激情视频| 亚洲免费精品| 日韩视频免费观看| 亚洲精品乱码久久久久久按摩观 | 99精品国产在热久久下载| 亚洲精品裸体| 亚洲精品免费网站| 日韩亚洲成人av在线| 99国产精品视频免费观看| 99re这里只有精品6| 夜夜夜久久久| 一本高清dvd不卡在线观看| 亚洲美女电影在线| 99国产精品一区| 99伊人成综合| 亚洲网站啪啪| 中文精品视频| 欧美一区二区三区四区夜夜大片 | 99www免费人成精品| 日韩一级在线观看| 亚洲午夜在线观看视频在线| 亚洲在线不卡| 久久免费偷拍视频| 免费观看成人www动漫视频| 欧美成人精品不卡视频在线观看| 久久午夜视频| 欧美成人免费网| 日韩视频中午一区|