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

CppExplore

一切像霧像雨又像風

  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
  29 隨筆 :: 0 文章 :: 280 評論 :: 0 Trackbacks

作者:CppExplore 地址:http://m.shnenglu.com/CppExplore/
(2)boost::pool
系列。boost的內存池最低層是simple_segregated_storage,類似于Loki中的chunk,在其中申請釋放block(boost中把block稱為chunk,暈死,這里還是稱其為block)采用了和loki的chunk中同樣的算法,不同的是simple_segregated_storage使用void*保存block的塊序號,loki中使用char,因此boost中的simple_segregated_storage沒有255的上限限制,自然也就不需要再其上再封裝一層類似與FixedAllocator的層面。另boost沒有屏蔽塊的大小,直接提供定長的接口給用戶,省掉了SmallObjAllocator層面。因此boost的內存池申請釋放block的時間復雜度都是O(1)(object_pool和pool_allocator除外),另避免的小內存的浪費,同時boost不能象loki那樣在將block歸還給內存池的時候根據chunk的空閑數量釋放內存歸還給系統,只能顯式調用釋放內存函數或者等內存池銷毀的時候,基本上和內存池生命周期內永不釋放沒什么區別。
    boost的最低層是simple_segregated_storage,主要算法和loki中的chunk一樣,不多說了。這里說下影響上層接口的兩類實現:add_block/malloc/free、add_ordered_block/malloc/ordered_free,兩種低層實現造成boost上層設計的成功與失敗,前者效率高,和loki一樣直接增加釋放,時間復雜度O(1),后者掃描排序,時間復雜度O(n)。
    boost提供了四種內存池模型供使用:pool、object_pool、singleton_pool、pool_allocator/fast_pool_allocator。
1)pool
基本的定長內存池

#include <boost/pool/pool.hpp>
typedef struct student_st
{
   
char name[10];
   
int age;
}
CStudent;
int main()
{
   boost::pool
<> student_pool(sizeof(CStudent));
   CStudent 
* const obj=(CStudent *)student_pool.malloc();
   student_pool.free(obj);
   
return 0;
}

    pool的模版參數只有一個分配子類型,boost提供了兩種default_user_allocator_new_delete/default_user_allocator_malloc_free,指明申請釋放內存的時候使用new/delete,還是malloc/free,默認是default_user_allocator_new_delete。構造函數有2個參數:nrequested_size,nnext_size。nrequested_size是block的大小(因為void*保存序號,因此boost內置了block的最小值,nrequested_size過小則取內置值),nnext_size是simple_segregated_storage中內存不足的時候,申請的block數量,默認是32。最全面的實例化pool類似這樣:boost::pool<boost::default_user_allocator_malloc_free> student_pool(sizeof(CStudent),255);
    pool提供的函數主要有:
malloc/free  基于add_block/malloc/free實現,高效
ordered_malloc/ordered_free 基于add_ordered_block/malloc/ordered_free實現,在pool中無任何意義,切勿使用。
release_memory/purge_memory 前者釋放池中未使用內存,后者釋放池中所有內存。另池析構也會釋放內存

2)object_pool

對象內存池,這是最失敗的一個內存池設計。

#include <boost/pool/object_pool.hpp>

class A{
public:
   A():data_(
0){}
private:
   
int data_;
}
;
int main()
{
   boost::object_pool
<A> obj_pool;
   A 
*const pA=obj_pool.construct();
   obj_pool.destroy(pA);
   
return 0;
}

    object_pool繼承至pool,有兩個模版參數,第一個就是對象類型,第二個是分配子類型,默認同pool是default_user_allocator_new_delete。構造函數參數只有nnext_size,意義以及默認值同pool。最全面的實例化object_pool類似這樣:boost::pool<A,boost::default_user_allocator_malloc_free> obj_pool(255);
object_pool提供的函數主要有(繼承至父類的略):
malloc/free 復寫pool的malloc/free,add_ordered_block/malloc/ordered_free實現
construct/destroy 基于本類的malloc/free實現,額外調用默認構造函數和默認析構函數。
~object_pool 單獨拿出這個說下,若析構的時候有對象未被destroy,可以檢測到,釋放內存前對其執行destroy
    為什么boost::object_pool要設計成這樣?能調用構造函數和析構函數顯然不是boost::object_pool類設計的出發點,因為構造函數只能執行默認構造函數(首次發表錯誤:可以調用任意的構造函數,參見代碼文件:boost/pool/detail/pool_construct.inc和boost/pool/detail/pool_construct_simple.inc,感謝eXile指正),近似于無,它的重點是內存釋放時候的清理工作,這個工作默認的析構函數就足夠了。apr_pool內存池中就可以注冊內存清理函數,在釋放內存的時刻執行關閉文件描述符、關閉socket等操作。boost::object_pool也想實現同樣的功能,因此設計了destroy這個函數,而同時為了防止用戶遺漏掉這個調用,而又在內存池析構的時候進行了檢測回收。為了這個目的而又不至于析構object_pool的時間復雜度是O(n平方),boost::object_pool付出了沉重的代價,在每次的destoy都執行排序功能,時間復雜度O(n),最后析構的時間復雜度是O(n),同樣為了這個目的,從simple_segregated_storage增加了add_ordered_block/ordered_free,pool增加了ordered_malloc/ordered_free等累贅多余的功能。
    基于上面討論的原因,boost::object_pool被設計成了現在的樣子,成了一個雞肋類。類的設計者似乎忘記了內存池使用的初衷,忘記了內存池中內存申請釋放的頻率很高,遠遠大于內存池對象的析構。如果你依然想使用類似于此的內存清理功能,可以在boost::object_pool上修改,不復寫malloc/free即可,重寫object_pool的析構,簡單釋放內存就好,因此析構object_pool前不要忘記調用destroy,這也是使用placement new默認遵守的規則,或者保持以前的析構函數,犧牲析構時的性能。placement new的作用是為已經申請好的內存調用構造函數,使用流程為(1)申請內存buf(2)調用placement new:new(buf)construtor()(3)調用析構destructor()(4)釋放內存buf。#include<new>可以使用placement new。
3)singleton_pool
pool的加鎖版本。

#include <boost/pool/singleton_pool.hpp>
typedef struct student_st
{
   
char name[10];
   
int age;
}
CStudent;
typedef struct singleton_pool_tag
{}singleton_pool_tag;
int main()
{
   typedef boost::singleton_pool
<singleton_pool_tag,sizeof(CStudent)>  global;
   CStudent 
* const df=(CStudent *)global::malloc();
   global::free(df);
   
return 0;
}

    singleton_pool為單例類,是對pool的加鎖封裝,適用于多線程環境,其中所有函數都是靜態類型。它的模版參數有5個,tag:標記而已,無意義;RequestedSize:block的長度;UserAllocator:分配子,默認還是default_user_allocator_new_delete;Mutex:鎖機制,默認值最終依賴于系統環境,linux下是pthread_mutex,它是對pthread_mutex_t的封裝;NextSize:內存不足的時候,申請的block數量,默認是32。最全面的使用singleton_pool類似這樣:typedef boost::singleton_pool<singleton_pool_tag,sizeof(CStudent),default_user_allocator_new_delete,details::pool::default_mutex,200>  global;
    它暴露的函數和pool相同。
4)pool_allocator/fast_pool_allocator
    stl::allocator的替換方案。兩者都是基于singleton_pool實現,實現了stl::allocator要求的接口規范。兩者的使用相同,區別在于pool_allocator的實現調用ordered_malloc/ordered_free,fast_pool_allocator的實現調用malloc/free,因此推薦使用后者。

#include <boost/pool/pool_alloc.hpp>
#include 
<vector>
typedef struct student_st
{
 
char name[10];
 
int age;
}
CStudent;

int main()
{
  std::vector
<CStudent *,boost::fast_pool_allocator<CStudent *> > v(8);
  CStudent 
*pObj=new CStudent();
  v[
1]=pObj;
  boost::singleton_pool
<boost::fast_pool_allocator_tag,sizeof(CStudent *)>::purge_memory(); 
  
return 0;
}

    fast_pool_allocator的模版參數有四個:類型,分配子,鎖類型,內存不足時的申請的block數量,后三者都有默認值,不再說了。它使用的singleton_pool的tag是boost::fast_pool_allocator_tag。
評價:boost::pool小巧高效,多多使用,多線程環境下使用boost::singleton_pool,不要使用兩者的ordered_malloc/ordered_free函數。boost::object_pool不建議使用,可以改造后使用。pool_allocator/fast_pool_allocator推薦使用后者。


未完 待續.................... 不過這個主題暫時不寫了 等有時間了
posted on 2008-02-20 15:09 cppexplore 閱讀(6755) 評論(21)  編輯 收藏 引用

評論

# re: 【原創】系統設計之 內存管理(三) 2008-02-20 19:07 空明流轉
確實,本來打算用obj_pool的,后來一看complexity,拉倒吧。。。  回復  更多評論
  

# re: 【原創】系統設計之 內存管理(三) 2008-02-20 23:15 eXile
我覺得lz對object_pool 的設計理念和如何使用都存在理解上的錯誤, 特別是以下幾點:
1) 構造函數只能執行默認構造函數
2) 設計了destroy這個函數,而同時為了防止用戶遺漏掉這個調用,而又在內存池析構的時候進行了檢測回收
3)為了這個目的而又不至于析構object_pool的時間復雜度是O(n平方)


object_pool 主要著眼于“自動析構”,在沒有gc的情況下,達到提高效率和自動管理內存的目的。而且它也特別適合于“多次申請,一次釋放”的情況.所以它甚至是鼓勵你忽略使用destroy(從它的例子就可以看出來)。

destroy函數并沒有提高復雜度,因為內部鏈表始終處于有序狀態(由于使用order_malloc,order_free),所以不論是逐個釋放,還是成批釋放,它的復雜度都是O(N)

  回復  更多評論
  

# re: 【原創】系統設計之 內存管理(三) 2008-02-21 09:08 cppexplore
另:boost/pool下的6個hpp文件我是挨個讀過了。detail下的都很簡單,5個hpp,singleton.hpp有效行數就10幾行,沒看,想當然了下。mutex和guard在讀singleton_pool.hpp的時候看了下linux下的mutex,順便還測試了下,gcd_lcm的兩個也很簡單,沒看,估計大約是2者求最小值的功能。
我一貫認為,明白原理,知道如何使用就好,深入具體細節就是浪費腦細胞,如果你要實現一個當然例外。  回復  更多評論
  

# re: 【原創】系統設計之 內存管理(三) 2008-02-21 10:29 cppexplore
@eXile
暈倒 在boost/pool/detail/pool_construct.inc里
只關注hpp去了
可以調用任意的構造函數
多謝指正!正文中現已標明。  回復  更多評論
  

# re: 【原創】系統設計之 內存管理(三) 2008-02-21 10:48 eXile
呵呵,不當之處,敬請原諒。
“多次申請,一次釋放”的情況,比如說對于服務器而言,從收到一個包,到對這個包的處理完畢,則可視為內存的一個周期。不過有時候異步完成,再加上object_pool只能管理一種對象,又限制了這種使用。  回復  更多評論
  

# re: 【原創】系統設計之 內存管理(三)[未登錄] 2008-02-21 11:06 cppexplore
@eXile
:)
“從收到一個包,到對這個包的處理完畢,則可視為內存的一個周期。”,這時候析構object_pool不恰當,因為以后還會收到包,內存還可循環被使用,這里還是應該調用destroy,而它的時間復雜度o(n),導致了真是不太適合使用。析構object_pool更不可取,時間復雜度不說,還有內存的再次申請,背離了內存池的初衷。  回復  更多評論
  

# re: 【原創】系統設計之 內存管理(三) 2008-02-21 11:12 eXile
這個倒不是問題,因為object_pool是可配置的, 它帶有一個模板參數UserAlloc, 可以自定義  回復  更多評論
  

# re: 【原創】系統設計之 內存管理(三)[未登錄] 2008-02-21 11:28 cppexplore
問題的關鍵不在UserAlloc,而是details::PODptr<size_type> 。除非你想在內存池之上實現這個內存池的UserAlloc(到底是先有雞還是先有蛋......),即便這樣,當前的object_pool析構最少也要付出o(n)的代價。  回復  更多評論
  

# re: 【原創】系統設計之 內存管理(三) 2008-02-21 11:50 eXile
呵呵,正是如此,UserAlloc可以使用一個全局的boost::pool來實現,所謂大pool套小pool, 不過如果object_pool設計時完全放棄destroy, 則可以取得更大的優化。  回復  更多評論
  

# re: 【原創】系統設計之 內存管理(三)[未登錄] 2008-02-21 11:52 cppexplore
暈倒..........................  回復  更多評論
  

# re: 【原創】系統設計之 內存管理(三) 2008-02-21 12:07 jazz
好久之前開始用pool,不過一直不用object_pool當時就看到order_mallc的o(n)復雜度。當時一直沒想明白 為什么用object_pool中為什么申請內存使用order_mallc來替代malloc。  回復  更多評論
  

# re: 【原創】系統設計之 內存管理(三) 2008-02-21 12:12 jazz
memory pool 本來是為提高性能,但是object_pool對于destroy-o(n)的性能怎么能夠容忍?  回復  更多評論
  

# re: 【原創】系統設計之 內存管理(三) 2008-02-21 14:02 空明流轉
我本來就是小塊的分配釋放,而且只需要單線程就夠了,所以一開始的時候寫了個自己的池,現在考慮用boost的環池替代。  回復  更多評論
  

# re: 【原創】系統設計之 內存管理(三) 2008-04-27 07:25 王貴陽
非常好,仔細研究。  回復  更多評論
  

# re: 【原創】技術系列之 內存管理(三) 2009-04-04 18:30 yshuise
object_pool設計成那樣的根本原因,就是還可以作為內存池使用。不是真正的釋放內存。所以,博主理解不對啊  回復  更多評論
  

# re: 【原創】技術系列之 內存管理(三)[未登錄] 2009-04-04 19:37 cppexplore
@yshuise
你確信你看懂它的實現了?  回復  更多評論
  

# re: 【原創】技術系列之 內存管理(三) 2011-08-10 11:57 sa
既然是一個定長的pool,為何simple_segregated_storage還要拆分成那么多chunk干嗎,直接把所有的obj通過一個linklist串在一起不就行了?  回復  更多評論
  

# re: 【原創】技術系列之 內存管理(三)[未登錄] 2011-08-10 12:30 cppexplore
@sa
原因: 1) 和linklist相比更節省內存 2)和linklist相比,申請/歸還內存更快  回復  更多評論
  

# re: 【原創】技術系列之 內存管理(三)[未登錄] 2011-10-20 21:54 chipset
看了三篇文章。不知道該說啥好,單CPU,DLMalloc足矣,其它我都不看好,最不看好用完最后一次性釋放的內存池,原因不解釋。

多CPU,ptmalloc3,或glib里的內存管理器(以ptmalloc3為基礎的改進),谷歌的TCMalloc,還有Free BSD的Jemalloc,以及Hoard。多CPU,碎片率低,好的線性加速比是關鍵,Jemalloc很強。TCMalloc看上去像個多CPU的自有列表內存管理器,加速比也不錯,且有垃圾收集,但是啟動速度跟啟動Java虛擬機絕對有一拼...這些都是免費的。至于那些要錢的,我懶得一提...  回復  更多評論
  

# re: 【原創】技術系列之 內存管理(三) 2011-12-16 12:21 cppexplore
@chipset
站在"造輪子"角度 / "使用輪子" 角度 /"選輪子"角度 看到的東西各有些不同.  回復  更多評論
  

# re: 【原創】技術系列之 內存管理(三)[未登錄] 2012-03-26 20:49 cexer
我覺得boost::pool的ordered_malloc和ordered_free函數是有必要的,它們是作為ordered pool的接口部分而存在的,使用場景不一樣,和malloc和free是沒有可比性。

boost::pool中有一個函數malloc_n用來申請幾塊連續的partition。一個block是以partition為粒度劃分,以單向鏈表鏈接起來,多次malloc/free的動作之后,這些partition在鏈表中的邏輯順序和它們在內存中的實際順序極有可能是不一致的,此時要得到連續的partition,必須要遍歷鏈表,找出在內存中實際連續的partition,并將它們在鏈表中的順序也重新以連續的順序鏈接,然后返回給調用者。

如果將鏈表的順序與內存中實際順序的不一致程度叫做它的無序度,顯然這個遍歷操作的耗費的時間,和鏈表的無序度是成正比的。如果這種malloc_n的操作很頻繁,那么這種遍歷鏈表重新鏈接的操作會很費時。

這種頻繁申請多個連續partition的場景下正是使用ordered pool的地方,正如pool作者在代碼寫的注釋那樣:
// Note: if you're allocating/deallocating n a lot, you should
// be using an ordered pool.

ordered pool內部的所有partition鏈表無序度為0,即所有partition在內存中的實際順序和它們在鏈表中的邏輯順序完全一致,對于malloc_n這樣的請求,可以更快滿足。也因此boost::pool提供了ordered版本的操作接口,這組接口保證每次free之后鏈表的順序不會亂。

不過,我個人覺得block以partition為粒度劃分是沒必要的,可以在收到請求的時候按實際需求劃分,盡力使整個塊保持連續,可以極大地避免產生碎片,降低ordered_malloc的ordered_free的時間。

當然ordered_xxx函數不應該和其它的函數混用,否則就是陪了夫人又折兵的買賣,即浪費了ordered_xxx的時間,又無法得到更快malloc_n的好處。
  回復  更多評論
  

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美国产综合视频| 亚洲精品国产精品国产自| 在线播放中文字幕一区| 欧美午夜一区二区三区免费大片| 免费视频最近日韩| 欧美精品久久久久久| 欧美理论电影在线观看| 国产精品成人在线| 国产亚洲欧美色| 亚洲国产日韩欧美在线动漫| 亚洲精品一级| 欧美一区二区三区日韩| 美女黄网久久| 一本久久精品一区二区| 欧美亚洲一区在线| 欧美高潮视频| 国产精品视频久久一区| 黄色一区二区三区四区| 日韩天堂av| 久久久精品久久久久| 亚洲国产裸拍裸体视频在线观看乱了中文 | 欧美一二三区在线观看| 久久免费视频在线| 亚洲精品午夜| 久久国产夜色精品鲁鲁99| 免费在线看一区| 国产欧美日韩在线观看| 亚洲精品系列| 久久久99精品免费观看不卡| 欧美国产在线观看| 亚洲欧美视频在线观看视频| 欧美r片在线| 国产日韩在线看| 一本色道久久88亚洲综合88| 久久久国产成人精品| 99亚洲伊人久久精品影院红桃| 久久九九久久九九| 国产精品视频第一区| 夜夜夜精品看看| 免费久久99精品国产自| 午夜久久影院| 国产精品亚洲综合一区在线观看| 亚洲精品一品区二品区三品区| 欧美在线一区二区三区| 国产美女搞久久| 国内精品久久久久影院优| 91久久国产综合久久91精品网站| 欧美在线观看你懂的| 亚洲精品极品| 男男成人高潮片免费网站| 国产亚洲精品v| 午夜欧美大尺度福利影院在线看| 亚洲精品乱码| 欧美精品日本| 亚洲精品中文字幕在线观看| 欧美成人影音| 欧美**字幕| 亚洲二区免费| 欧美bbbxxxxx| 毛片av中文字幕一区二区| 亚洲丰满在线| 亚洲二区免费| 欧美激情 亚洲a∨综合| 亚洲欧洲一区| 亚洲日本成人| 欧美午夜视频网站| 性亚洲最疯狂xxxx高清| 午夜久久tv| 精品999日本| 欧美多人爱爱视频网站| 欧美r片在线| 中文日韩在线| 亚洲一区二区欧美| 国产亚洲精品aa| 欧美高清视频一区| 欧美日韩国内| 久久er99精品| 麻豆久久久9性大片| 亚洲精品一区在线观看| 99亚洲伊人久久精品影院红桃| 国产精品美腿一区在线看| 欧美在线三级| 欧美xx69| 午夜欧美大尺度福利影院在线看 | 亚洲免费成人av| 欧美色图首页| 久久久五月天| 欧美久久久久久久久| 性做久久久久久久免费看| 久久福利毛片| av成人动漫| 欧美一级片久久久久久久 | 欧美亚洲一区在线| 久久亚洲精品网站| 亚洲一区二区免费| 久久久天天操| 亚洲在线1234| 你懂的国产精品永久在线| 亚洲视频一区二区| 久久久噜噜噜久久久| 亚洲香蕉视频| 欧美va天堂va视频va在线| 亚洲综合视频在线| 亚洲免费福利视频| 欧美在线观看一区二区三区| 亚洲精品久久久久久久久久久 | 久久综合影音| 欧美性色aⅴ视频一区日韩精品| 久久久免费av| 国产精品激情| 亚洲欧洲日产国码二区| 国产自产2019最新不卡| 日韩一级片网址| 亚洲精品乱码久久久久| 久久九九热re6这里有精品| 亚洲综合精品自拍| 欧美全黄视频| 亚洲激情一区二区三区| 加勒比av一区二区| 午夜免费久久久久| 亚洲欧美日韩综合aⅴ视频| 欧美黑人多人双交| 欧美黄免费看| 亚洲国产精品精华液2区45| 久久大综合网| 久久视频精品在线| 国产亚洲欧美另类一区二区三区| 99国产精品99久久久久久粉嫩| 亚洲国产综合91精品麻豆| 久久久国产午夜精品| 久久久久久久精| 国产真实乱偷精品视频免| 亚洲欧美日本伦理| 久久www成人_看片免费不卡| 国产精品国产三级国产普通话99| 亚洲精品欧美日韩专区| 日韩一二三区视频| 欧美日韩中文字幕精品| 一本色道久久综合精品竹菊| 国产精品99久久久久久白浆小说| 欧美日韩精品免费| 亚洲视频导航| 久久国产精品色婷婷| 国产丝袜一区二区三区| 久久av红桃一区二区小说| 久久综合国产精品台湾中文娱乐网| 国产亚洲永久域名| 久久亚洲私人国产精品va媚药| 欧美成人精品在线观看| 亚洲精品国产精品国自产在线| 欧美成人一区二区三区| 99视频在线精品国自产拍免费观看| 亚洲图片在线观看| 国产啪精品视频| 久久亚洲精选| 亚洲精品视频在线播放| 亚洲欧美一级二级三级| 国产亚洲精品一区二555| 久久久午夜电影| 亚洲精品乱码久久久久久蜜桃麻豆| 一区二区三区视频免费在线观看| 国产精品初高中精品久久| 亚洲女女女同性video| 久久夜色精品国产噜噜av| 亚洲娇小video精品| 国产精品成人一区二区三区吃奶| 午夜精品福利视频| 欧美激情视频一区二区三区免费| 一区二区欧美日韩视频| 国产一区二区三区不卡在线观看 | 一区二区三区毛片| 欧美亚日韩国产aⅴ精品中极品| 在线综合视频| 蜜桃av久久久亚洲精品| 在线亚洲观看| 影音欧美亚洲| 国产精品久久久久天堂| 久久亚洲一区二区| 亚洲欧美日韩国产一区二区三区| 欧美v国产在线一区二区三区| 一本色道久久综合狠狠躁的推荐| 国产香蕉97碰碰久久人人| 欧美激情一区二区三区不卡| 欧美一区二区成人6969| 日韩视频精品| 欧美福利视频在线观看| 欧美中文字幕视频在线观看| aⅴ色国产欧美| 亚洲福利免费| 国内精品视频一区| 国产精品视频精品视频| 欧美日韩99| 女人香蕉久久**毛片精品| 香蕉成人伊视频在线观看 | 久久天天狠狠| 性欧美长视频| 亚洲午夜高清视频| 亚洲精品国产系列| 伊人久久综合97精品| 国产色综合久久|