今天在看ACE内存分配的时候(太多,没看完),发现分配策略不全,我想实现一个能缓存,高效,内存总量不限的分配策略用于对 ACE_Message_Block对象的缓存,虽然ACE_Message_Block支持为它设置三种分配器,一个是对ACE_Message_Block对象本身message_block_allocator_,一个是对ACE_Data_Block本身data_block_allocator_,还有一个是对ACE_Data_Block的数据缓冲区的分配器allocator_strategy_,但是感觉ACE的分配器实现起来复杂,方法也多,就自己实现了一个,下面是部分代码,仅供参考
// MemPoolT.h
/**/
/**
* @date 2007.10.25
* @author PeakGao <peakgao163@163.com>
*/
#ifndef OM_MEMPOOLT_H
#define
OM_MEMPOOLT_H
![]()
#include
<
assert.h
>
#include
<
ace
/
guard_t.h
>
#include
<
ace
/
global_macros.h
>
![]()
![]()
namespace
om
{
![]()
![]()
/**//**
缓冲池
![]()
缓存池采取2维内存缓冲机制,每次new出一个缓冲链,每个缓冲链为
<GrowBlockCount>个大小为<BlockSize>的内存块,缓冲链之间建立链表关
系。
![]()
优点:
1、缓冲池大小由小变大,动态增长,不是一开始就分配一个超大的内
存,真正按需分配;
2、不存在realloc,缓冲地址固定不变;
3、支持FreeList,高效;
![]()
缺点:
1、分配的对象在长时间不用时没有实现智能释放,以后有需要再改
![]()
要求:
1、每个块的大小必须大于等于sizeof(Node),32位系统上面是4字节
![]()
示例:
@code
class MyObj
{
public:
MyObj()
{
std_out<<ACE_TEXT("MyObj::MyObj()")<<std_endl;
}
~MyObj()
{
std_out<<ACE_TEXT("MyObj::~MyObj()")<<std_endl;
}
void foo()
{
std_out<<ACE_TEXT("MyObj::foo()")<<std_endl;
}
int dummy;
};
![]()
void test()
{
using namespace om;
typedef CachePoolWithLock<ACE_Lock_Adapter<ACE_SYNCH_MUTEX> > CachePool_Lock;
![]()
CachePool p1;
p1.create(1024, 256);
void* pp1 = p1.alloc();
p1.free(pp1);
p1.clear();
![]()
CachePool_Lock p2(7, 256);
void* pp2 = p2.alloc();
p2.free(pp2);
p2.clear();
![]()
![]()
ObjectPool<MyObj, CachePool_Lock> pool(128);
MyObj* o = pool.alloc();
o->foo();
pool.free(o);
pool.clear();
}
@endcode
*/
![]()
#define BYTE_ALIGN_8 /// 是否支持块尺寸8字节对齐的开关宏
![]()
![]()
![]()
/**//**
缓存池
这里只实现逻辑,不考虑线程安全,线程安全的版本见下面的CachePoolWithLock模版
*/
class CachePool
![]()
{
protected:
![]()
![]()
/**//// 缓冲链: Head + cache1 + cache2 + cacheN (N=BlockCount)
struct Chain
![]()
{
Chain* _Next;
![]()
![]()
void* data()
{ return this + 1; }
![]()
inline static Chain* create(Chain*& head, size_t blockSize, size_t blockCount)
![]()
{
#if defined(BYTE_ALIGN_8)
blockSize = blockSize ? ((blockSize + 7) & ~7) : 8; // 8字节对齐
#endif
Chain* p = (Chain*) new char[sizeof(Chain) + blockCount * blockSize];
![]()
p->_Next = head;
return head = p;
}
![]()
void free()
![]()
{
Chain* p = this;
while (p)
![]()
{
char* buf = (char*)p;
Chain* next = p->_Next;
delete[] buf;
p = next;
}
}
};
![]()
![]()
![]()
/**//// 空闲对象节点,仅仅在空闲对象中有效
struct Node
![]()
{
Node* _Next;
};
![]()
![]()
![]()
size_t _BlockSize; /**//// 数据块的字节大小
![]()
size_t _GrowBlockCount; /**//// 每次连续分配的块数
![]()
Chain* _ChainList; /**//// 每次分配的缓冲链
![]()
Node* _FreeNode; /**//// 当前空闲节点
![]()
public:
![]()
/**//// 默认构造,注意必须调用create方法初始化参数
CachePool()
: _BlockSize(0), _GrowBlockCount(0), _ChainList(0), _FreeNode(0)
![]()
{
}
![]()
CachePool(size_t blockSize, size_t growBlockCount)
: _ChainList(0), _FreeNode(0)
![]()
{
create(blockSize, growBlockCount);
}
![]()
~CachePool()
![]()
{
clear();
}
![]()
![]()
/**//// 清除所有的内存空间
void clear()
![]()
{
if (_ChainList)
![]()
{
_ChainList->free();
_ChainList = 0;
_FreeNode = 0;
}
}
![]()
![]()
/**//// 初始化参数
void create(size_t blockSize, size_t growBlockCount)
![]()
{
_BlockSize = blockSize;
_GrowBlockCount = growBlockCount;
![]()
assert(_GrowBlockCount >= 1);
assert(_BlockSize >= sizeof(Node));
}
![]()
![]()
/**//// 获取块的大小
size_t getBlockSize() const
![]()
{
return _BlockSize;
}
![]()
![]()
/**//// 获取连续分配的块的数目
size_t getGrowBlockCount() const
![]()
{
return _GrowBlockCount;
}
![]()
![]()
/**//// 分配一个块内存
void* alloc()
![]()
{
assert(_GrowBlockCount >= 1);
assert(_BlockSize >= sizeof(Node));
![]()
if (_FreeNode == 0)
![]()
{
// 分配另一个数据链
Chain* newChain = Chain::create(_ChainList, _BlockSize, _GrowBlockCount);
![]()
Node* node = (Node*)newChain->data();
![]()
// 定位到最后一个节点
(char*&)node += _BlockSize * (_GrowBlockCount - 1);
![]()
// 建立连接关系
for (int i=(int)_GrowBlockCount-1; i>=0; i--, (char*&)node -= _BlockSize)
![]()
{
node->_Next = _FreeNode;
_FreeNode = node;
}
}
![]()
assert(_FreeNode != 0);
![]()
void* block = (void*)_FreeNode;
_FreeNode = _FreeNode->_Next;
![]()
return block;
}
![]()
![]()
/**//// 释放块内存
void free(void* block)
![]()
{
if (block != 0)
![]()
{
Node* node = (Node*)block;
node->_Next = _FreeNode;
_FreeNode = node;
}
}
};
![]()
![]()
![]()
![]()
![]()
/**//**
支持锁策略的缓存池,目前用的ACE的锁,可以很方便的改为其他的锁策略
比如_ACELOCK可以为锁对象ACE_Lock_Adapter<ACE_SYNCH_MUTEX>,也可以
直接用互斥体如ACE_SYNCH_NULL_MUTEX
*/
template<class ACELOCK>
class CachePoolWithLock : public CachePool
![]()
{
protected:
![]()
ACELOCK _Lock; /**//// 锁
![]()
public:
CachePoolWithLock()
![]()
{
}
![]()
CachePoolWithLock(size_t blockSize, size_t growBlockCount)
: CachePool(blockSize, growBlockCount)
![]()
{
}
![]()
![]()
/**//// 清除所有的内存空间
void clear()
![]()
{
ACE_GUARD(ACELOCK, ace_mon, _Lock);
CachePool::clear();
}
![]()
![]()
/**//// 分配一个块内存
void* alloc()
![]()
{
ACE_GUARD_RETURN(ACELOCK, ace_mon, _Lock, NULL);
return CachePool::alloc();
}
![]()
![]()
/**//// 释放块内存
void free(void* block)
![]()
{
ACE_GUARD(ACELOCK, ace_mon, _Lock);
CachePool::free(block);
}
};
![]()
![]()
/**//**
对象池
在缓冲池的基础上,增加了对象的构造和析构为了更好扩充,模版参数直接传入缓冲池类型,可
以是上面的CachePool、CachePoolWithLock,也可以是用户自定义的缓冲池,但必须符合调用规范
*/
template<class T, class CachePoolStrategy>
class ObjectPool : public CachePoolStrategy
![]()
{
protected:
typedef CachePoolStrategy _Base;
![]()
public:
ObjectPool()
![]()
{
}
![]()
ObjectPool(size_t growBlockCount)
: _Base(sizeof(T), growBlockCount)
![]()
{
}
![]()
![]()
/**//// 初始化参数
void create(size_t growBlockCount)
![]()
{
_Base::create(sizeof(T), growBlockCount);
}
![]()
![]()
/**//// 创建对象的内存空间,但是没有进行构造,用户可以自行进行定制的构造
T* alloc()
![]()
{
void* obj = _Base::alloc();
::new (obj) T(); // 只提供了采用默认构造的方式
return (T*)obj;
}
![]()
![]()
/**//// 释放对象
void free(T* obj)
![]()
{
if (obj != 0)
![]()
{
obj->~T();
_Base::free(obj);
}
}
};
![]()
}
//
namespace om
#endif
//
OM_MEMPOOLT_H
// MemPoolT.h