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

隨筆-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>
            久久爱91午夜羞羞| 国产一区二区三区在线免费观看| 国产乱子伦一区二区三区国色天香| 伊人久久av导航| 亚洲国产成人在线| 奶水喷射视频一区| 99精品99久久久久久宅男| 日韩视频免费观看高清在线视频 | 亚洲国产婷婷香蕉久久久久久99| 免费亚洲电影在线观看| 99精品视频一区| 亚洲一区黄色| 一区二区三区亚洲| 亚洲人www| 国产欧美一区二区精品秋霞影院| 久久久久久久999| 欧美福利精品| 久久狠狠亚洲综合| 欧美日本高清| 久久免费视频网站| 欧美日韩99| 久久亚洲不卡| 欧美性久久久| 欧美国产综合视频| 国产欧美不卡| 亚洲欧洲一级| 一区二区在线视频播放| 一本大道久久a久久综合婷婷| 国内精品美女av在线播放| 亚洲大胆人体在线| 国产一区二区三区黄| 亚洲毛片在线| 亚洲电影第三页| 亚洲桃色在线一区| 99re6热在线精品视频播放速度| 亚洲一区视频在线| 日韩一级片网址| 亚洲国产精品欧美一二99| 午夜久久久久久| 免费91麻豆精品国产自产在线观看| 一区二区三区四区五区视频| 久久久精品国产99久久精品芒果| 一本色道久久综合亚洲精品按摩 | 国产精品日韩在线| 亚洲欧洲一区二区在线观看| 国产精品视屏| 99国产精品视频免费观看一公开| 曰本成人黄色| 久久超碰97人人做人人爱| 亚洲一级电影| 欧美日韩国产一区精品一区 | 亚洲一区在线免费| 中文在线一区| 欧美日本二区| 亚洲免费播放| 亚洲性感美女99在线| 欧美精品不卡| 91久久久一线二线三线品牌| 最新成人av网站| 模特精品在线| 亚洲精品日韩在线观看| 亚洲精品国产精品国产自| 久久综合久久综合九色| 欧美粗暴jizz性欧美20| 亚洲第一在线综合网站| 久久嫩草精品久久久精品| 久久免费99精品久久久久久| 国语自产精品视频在线看抢先版结局 | 亚洲一区二区三| 午夜在线观看免费一区| 国产精品日韩在线播放| 亚洲欧美日韩天堂一区二区| 欧美在线播放高清精品| 国产视频丨精品|在线观看| 午夜免费在线观看精品视频| 久久国产福利国产秒拍| 国语自产在线不卡| 免费视频一区| 在线亚洲精品福利网址导航| 亚洲欧美日韩久久精品| 国产一区二区三区av电影| 久久久精品一品道一区| 欧美大片91| 亚洲网友自拍| 国产精品久久久久久久免费软件| 亚洲一区二区三区在线看| 久久婷婷av| 99精品福利视频| 国产情人节一区| 免费成年人欧美视频| 日韩亚洲欧美成人| 久久精品免费观看| 亚洲美女黄色| 国产欧美日韩在线播放| 免费永久网站黄欧美| 国产精品乱码久久久久久| 日韩视频专区| 欧美在线亚洲| 亚洲欧洲三级电影| 国产精品久久久久9999| 久久久国产精品一区二区中文 | 激情综合激情| 欧美视频日韩视频在线观看| 欧美亚洲一区二区在线| 亚洲国产精品一区制服丝袜| 午夜一区在线| 99re热这里只有精品视频| 国产三级欧美三级日产三级99| 女人香蕉久久**毛片精品| 亚洲午夜在线| 91久久精品美女高潮| 久久国产精品久久w女人spa| 日韩午夜在线| 亚洲电影观看| 国产在线视频欧美| 国产精品v欧美精品v日韩精品| 久久一二三四| 欧美一区三区二区在线观看| 日韩午夜一区| 亚洲第一精品夜夜躁人人躁| 久久综合亚洲社区| 午夜精品久久久久久久久久久久| 亚洲黄色在线看| 一区二区亚洲精品国产| 国产精品夜夜嗨| 国产精品福利在线| 欧美精品麻豆| 欧美jizzhd精品欧美喷水 | 亚洲高清自拍| 久久久久久久网站| 欧美一区二区三区日韩视频| 亚洲视频一二区| 日韩一区二区电影网| 亚洲第一视频| 亚洲电影在线观看| 在线视频观看日韩| 激情久久综合| 一区在线播放| 亚洲电影免费| 亚洲国产影院| 亚洲欧洲日本一区二区三区| 亚洲欧洲视频在线| 99精品视频免费全部在线| 99精品视频一区| 亚洲一区二区在线播放| 亚洲一区二区三区免费在线观看| 夜色激情一区二区| 亚洲天堂成人在线视频| 亚洲一区在线视频| 欧美亚洲网站| 久久久国际精品| 久久综合亚州| 亚洲黄色一区| 一区二区三区国产精华| 亚洲在线中文字幕| 欧美资源在线观看| 牛夜精品久久久久久久99黑人 | 欧美特黄视频| 国产女主播一区二区三区| 国产一区二区三区最好精华液| 国产亚洲成av人片在线观看桃| 狠狠综合久久| 亚洲精一区二区三区| 亚洲午夜激情在线| 久久精品视频导航| 亚洲第一狼人社区| 一区二区三区欧美视频| 狠狠色综合色综合网络| 一区二区三区我不卡| 国产精品一区在线播放| 韩国成人精品a∨在线观看| 亚洲黄页视频免费观看| 亚洲私人影吧| 久久综合导航| 亚洲免费观看在线视频| 午夜亚洲精品| 欧美精品电影在线| 国产日韩欧美综合| 亚洲精品在线电影| 欧美在线免费视频| 亚洲第一精品夜夜躁人人爽| 亚洲视频一区在线观看| 久久亚洲不卡| 国产精品试看| 亚洲精品国产精品国产自| 久久精品亚洲精品国产欧美kt∨| 欧美国产综合视频| 欧美一级专区| 欧美日韩一区视频| 亚洲第一精品在线| 久久精品一本| 夜夜嗨一区二区| 噜噜噜在线观看免费视频日韩| 欧美视频免费| 亚洲精品一区二区网址| 美国十次成人| 欧美在线地址| 国产精品视频网| 亚洲视频1区| 亚洲精品视频免费观看|