天天看點

ACE的記憶體配置設定介紹

一、記憶體配置設定器相關

ACE_Allocator

基類

ACE_New_Allocator : public ACE_Allocator

傳統的new和delete的動态記憶體配置設定器,主要方法:

malloc 配置設定一定大小的記憶體,實質就是new char[nbytes];

calloc 同上,但帶記憶體初始化

free 釋放指定的記憶體塊,實質就是delete[] ptr;

ACE_Static_Allocator_Base : public ACE_Allocator

靜态記憶體配置設定器,一次性配置設定一個大記憶體,比如200M,然後在200M内配置設定(已經不能叫配置設定了)指定大小的記憶體塊

成員:

char *buffer_; /// 緩沖區首位址

size_t size_;  /// 緩沖區的大小

size_t offset_;/// 目前配置設定位置

主要方法:

malloc 配置設定一定大小的記憶體,實質就是buffer_ + offset_ + nbytes,當超過size_時配置設定失敗

calloc 同上,但帶記憶體初始化

free 釋放指定的記憶體塊,實質是空操作

從實質來看隻适合預知消耗記憶體大小而且一般不進行釋放操作的情況下,因為釋放後的記憶體沒有得到應用

template <class MALLOC>

class ACE_Allocator_Adapter : public ACE_Allocator

記憶體配置設定擴充卡,對各種各樣的記憶體配置設定類進行适配,使之符合ACE_Allocator接口,MALLOC是具體的記憶體

配置設定實作,比如上面的ACE_New_Allocator,ACE_Static_Allocator_Base和使用者自定義的配置設定器

二、空閑清單

template <class T>

class ACE_Cached_Mem_Pool_Node

支援可緩存的對象節點,可用于空閑連結清單(free_list),實作了set_next和get_next

成員:

ACE_Cached_Mem_Pool_Node<T>* next_;

template <class T>

class ACE_Free_List

模版基類

主要方法:

add 加入一個節點到空閑連結清單

remove 移除一個空閑節點(給使用者使用)

size 連結清單目前有效的空閑節點個數

resize 重新設定連結清單節點個數

template <class T, class ACE_LOCK>

class ACE_Locked_Free_List : public ACE_Free_List<T>

帶鎖政策的空閑清單,其實除了鎖政策,它還有其他幾個特點:

1、可以定制為一個純空閑清單,就是内部不調用new/delete,由外部處理,在構造時将mode傳入

ACE_PURE_FREE_LIST即可,預設是ACE_FREE_LIST_WITH_POOL,表示内部在需要時可以調用new/delete進行操作;

2、支援水位(water mark)的概念,一個低水位(lwm),一個高水位(hwm),水位隻對mode為ACE_FREE_LIST_WITH_POOL時起作用

3、當節點不夠時,支援一次性遞增inc個節點(N由使用者在構造時傳入),隻對mode為ACE_FREE_LIST_WITH_POOL時起作用

主要方法:

add 加入一個節點(可能是使用者用完了的節點),如果mode為ACE_PURE_FREE_LIST或者mode為ACE_FREE_LIST_WITH_POOL而size<hwm時允許加入,否則delete掉

remove 從空閑連結清單移除一個節點(給使用者使用),當mode為ACE_FREE_LIST_WITH_POOL而size<=lwm時,表示節點數過少,系統會配置設定inc個節點出來以解燃眉之急,如果是ACE_PURE_FREE_LIST模式,當節點數為0時,remove将傳回NULL

resize 當mode為ACE_FREE_LIST_WITH_POOL時有意義,resize>size時,配置設定resize-size個節點,否則釋放size-resize個節點

舉例:

class MyClass

{

 int dummy;

public:

 MyClass() : dummy(99) {}

 void foo()

 {

  std::cout<<dummy<<std::endl;

 }

};

void test()

{

 ACE_Locked_Free_List< ACE_Cached_Mem_Pool_Node< MyClass >, ACE_SYNCH_NULL_MUTEX>  freeList; // 用ACE_SYNCH_NULL_MUTEX不需要同步,等同于單線程

 // 取出一個(配置設定一個)

 ACE_Cached_Mem_Pool_Node< MyClass >* node = freeList.remove();

 MyClass* mc = node.addr();

 // 用一下

 mc->foo();

 // 不用了,釋放掉

 freeList.add(node);

}

三、各種記憶體配置設定政策

template <class T, class ACE_LOCK>

class ACE_Cached_Allocator : public ACE_New_Allocator

有緩存功能的動态配置設定器,采用空閑連結清單進行節點管理,空閑連結清單的mode為ACE_PURE_FREE_LIST,即真正的new/delete由ACE_Cached_Allocator自己操作,

構造時可指定初始化T節點的個數,節點的大小由sizeof(T)決定,同時進行位元組對齊。

注意:

該配置設定器内部對T類型沒有進行構造和析構,是以不适合class使用,可用于struct,并且該配置設定器不支援自動增大記憶體區(也就是pool_成員在構造時就确定了)

,當記憶體不夠時,配置設定會失敗。

主要成員:

char *pool_; /// 記憶體塊

ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<T>, ACE_LOCK> free_list_;  /// 空閑節點管理

主要方法:

malloc 配置設定一個T節點,實際就是 return free_list_.remove()->addr();

calloc 同上,但會初始化記憶體資料

free 釋放一個T節點,實際就是 free_list_.add ((ACE_Cached_Mem_Pool_Node<T> *) ptr);

template <class ACE_LOCK>

class ACE_Dynamic_Cached_Allocator : public ACE_New_Allocator

同上,但是沒有T模版參數,多了一個成員chunk_size_,每個節點的大小由使用者自行定義,同樣不存在構造和析構功能,僅僅停留在固定節點大小的緩沖區的管理,内部沒有進行位元組對齊。

template <size_t POOL_SIZE>

class ACE_Static_Allocator : public ACE_Static_Allocator_Base

基于堆棧的靜态記憶體配置設定器,POOL_SIZE為堆棧大小