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

隨筆-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>
            亚洲国产精品va| 久久九九精品99国产精品| 久久亚洲国产成人| 香蕉免费一区二区三区在线观看| 国产精品久久久久9999吃药| 午夜国产精品影院在线观看| 亚洲线精品一区二区三区八戒| 国产精品美女久久久免费| 亚洲欧美中日韩| 欧美自拍偷拍| 亚洲黄色成人久久久| 亚洲精品一二| 欧美三区不卡| 久久国产精品99精品国产| 久久久久久久成人| 亚洲国产日韩一级| 一本大道久久精品懂色aⅴ| 欧美性淫爽ww久久久久无| 亚洲欧美一区二区激情| 久久国产一区| 日韩一二在线观看| 亚洲女爱视频在线| 尹人成人综合网| 亚洲精品中文字幕女同| 国产精品亚洲成人| 久久最新视频| 国产精品99一区| 久久蜜桃av一区精品变态类天堂| 亚洲欧美另类久久久精品2019| 久久蜜臀精品av| 欧美黄色影院| 欧美在线观看视频一区二区| 久久视频精品在线| 亚洲午夜国产成人av电影男同| 欧美中文在线观看国产| 亚洲精品日韩激情在线电影| 午夜精品视频| 一本色道**综合亚洲精品蜜桃冫| 欧美一区二区三区久久精品茉莉花| 亚洲国产导航| 欧美一区二区精品| 在线亚洲美日韩| 久久综合导航| 久久激情中文| 欧美少妇一区| 亚洲日本中文字幕| 在线播放亚洲一区| 亚洲欧美区自拍先锋| 99国产精品久久久久老师| 欧美有码在线观看视频| 亚洲综合视频网| 欧美人体xx| 亚洲第一网站免费视频| 精品69视频一区二区三区| 亚洲午夜视频| 亚洲天堂网在线观看| 欧美精彩视频一区二区三区| 欧美jjzz| 亚洲福利视频二区| 久久婷婷蜜乳一本欲蜜臀| 久久精品国产亚洲一区二区| 国产精品国色综合久久| 日韩一级网站| 亚洲色图制服丝袜| 欧美紧缚bdsm在线视频| 亚洲国产裸拍裸体视频在线观看乱了中文 | 亚洲精品一区二区三区99| 在线日韩成人| 六月丁香综合| 亚洲第一精品夜夜躁人人爽 | 国产精品久久久久av免费| 日韩视频免费| 亚洲综合日韩在线| 国产欧美午夜| 欧美淫片网站| 久久久噜噜噜久久中文字幕色伊伊 | 欧美精品亚洲一区二区在线播放| 亚洲国产成人久久综合一区| 最近看过的日韩成人| 欧美激情精品久久久久久蜜臀| 亚洲国产mv| 亚洲一区在线免费观看| 国产精品露脸自拍| 亚洲欧美一区二区三区极速播放 | 亚洲精品一线二线三线无人区| 国产永久精品大片wwwapp| 欧美在线观看视频| 免费人成精品欧美精品| 亚洲精品美女| 国产精品hd| 欧美制服第一页| 欧美大片一区二区三区| 一区二区国产在线观看| 欧美色精品天天在线观看视频| 性高湖久久久久久久久| 欧美高清在线观看| 亚洲午夜一区二区| 国产日韩精品一区二区三区在线| 久久精品国产精品亚洲| 亚洲人成欧美中文字幕| 久久超碰97人人做人人爱| 黑人巨大精品欧美一区二区小视频 | 日韩一本二本av| 久久久国产成人精品| 91久久综合亚洲鲁鲁五月天| 国产精品久久国产精麻豆99网站| 久久精品99久久香蕉国产色戒| 亚洲人成在线观看网站高清| 欧美一区二区三区日韩| 亚洲国产老妈| 国产精品尤物福利片在线观看| 久久天天狠狠| 亚洲一卡久久| 亚洲大胆在线| 久久亚洲春色中文字幕| 亚洲一区二区3| 亚洲激情偷拍| 国内精品久久国产| 欧美小视频在线观看| 免费不卡视频| 欧美一区二区三区视频免费播放| 亚洲欧洲综合另类在线| 久久九九99| 亚洲永久精品大片| 一二三区精品| 亚洲春色另类小说| 国产欧美日韩亚洲| 欧美日韩系列| 欧美国产日韩一区二区| 久久午夜精品| 午夜影院日韩| 欧美一进一出视频| 亚洲小视频在线| 亚洲伦理网站| 亚洲伦伦在线| 亚洲美女中出| 亚洲欧洲在线一区| 亚洲国产一区二区三区a毛片| 美日韩丰满少妇在线观看| 久久精品视频播放| 久久aⅴ国产紧身牛仔裤| 午夜精彩国产免费不卡不顿大片| 一区二区三区**美女毛片| av成人免费在线观看| 99热在线精品观看| 日韩亚洲欧美在线观看| 99精品欧美一区二区三区综合在线| 在线日韩电影| 亚洲三级观看| 一本久久综合亚洲鲁鲁| 亚洲一区二区三区乱码aⅴ蜜桃女| 一本色道久久88亚洲综合88| 日韩亚洲不卡在线| 99re66热这里只有精品4| 亚洲精品日韩激情在线电影 | 欧美一区国产在线| 欧美 日韩 国产在线| 久久这里只有| 麻豆精品视频在线观看| 亚洲国产精品99久久久久久久久| 亚洲福利av| 99视频+国产日韩欧美| 日韩视频国产视频| 亚洲天堂免费在线观看视频| 亚洲一区二区三区欧美 | 久久天天躁夜夜躁狠狠躁2022| 久久九九久久九九| 免费看亚洲片| 99热这里只有精品8| 性欧美大战久久久久久久免费观看 | 性做久久久久久久久| 久久午夜羞羞影院免费观看| 欧美激情亚洲自拍| 亚洲免费高清| 久久成人精品电影| 六十路精品视频| 国产精品v日韩精品| 国产原创一区二区| 91久久精品日日躁夜夜躁国产| 亚洲视频中文| 裸体歌舞表演一区二区| 亚洲激情小视频| 亚洲在线国产日韩欧美| 老牛嫩草一区二区三区日本| 欧美日韩国产精品专区| 国产午夜精品久久久久久免费视| 亚洲日本无吗高清不卡| 欧美专区在线| 亚洲电影欧美电影有声小说| 一区二区三区四区五区精品| 久久久久国产精品一区三寸| 欧美日韩一区在线视频| 国内精品一区二区三区| 一本色道久久综合亚洲91| 久久精品三级| 亚洲伊人一本大道中文字幕| 欧美激情91| 一区在线视频观看| 羞羞答答国产精品www一本| 亚洲国产天堂久久国产91|