今天在看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出一个缓冲链,每个缓冲链为
<BlockCount>个大小为<BlockSize>的内存块,缓冲链之间建立链表关
系。
优点:
1、不存在realloc,缓冲地址固定不变;
2、缓冲池大小由小变大,动态增长,不是一开始就分配一个超大的内
存,真正按需分配;
3、支持锁策略,目前用的ACE的锁,可以很方便的改为其他的锁策略;
4、支持FreeList,高效;
缺点:
1、分配的对象在长时间不用时不能智能释放
要求:
1、每个块的大小必须大于等于sizeof(CacheNode)
示例:
typedef CachePool<ACE_SYNCH_NULL_MUTEX> CachePool_NullMutex; // 单线程
typedef CachePool<ACE_SYNCH_MUTEX> CachePool_Mutex; // 多线程
CachePool_Mutex pool(1024, 256)
void* buf = pool.alloc();
pool.free(buf);
pool.clear();
*/
template<class _ACEMutex>
class CachePool
{
protected:
/**//// 缓冲链: Head + cache1 + cache2 + cacheN (N=BlockCount)
struct CacheChain
{
CacheChain* _Next;
void* data() { return this + 1; }
inline static CacheChain* create(CacheChain*& head, size_t blockSize, size_t blockCount)
{
CacheChain* p = (CacheChain*) new char[sizeof(CacheChain) + blockCount * blockSize];
p->_Next = head;
return head = p;
}
void free()
{
CacheChain* p = this;
while (p)
{
char* buf = (char*)p;
CacheChain* next = p->_Next;
delete[] buf;
p = next;
}
}
};
/**//// 空闲对象节点,仅仅在空闲对象中有效
struct CacheNode
{
CacheNode* _Next;
};
size_t _BlockSize; /**//// 数据块的字节大小
size_t _BlockCount; /**//// 每次连续分配的块数
CacheChain* _ChainList; /**//// 每次分配的缓冲链
CacheNode* _FreeNode; /**//// 当前空闲节点
_ACEMutex* _Mutex; /**//// 线程互斥体
bool _DeleteMutex; /**//// 是否在析构的时候删除互斥体
public:
CachePool()
: _BlockSize(0), _BlockCount(0), _ChainList(0), _FreeNode(0), _Mutex(0), _DeleteMutex(false)
{
}
CachePool(size_t blockSize, size_t blockCount, _ACEMutex* mutex = 0)
: _ChainList(0), _FreeNode(0), _Mutex(mutex)
{
create(blockSize, blockCount, mutex);
}
~CachePool()
{
if (_Mutex != 0 && _DeleteMutex)
{
clear();
delete _Mutex;
_Mutex = 0;
_DeleteMutex = false;
}
}
/**//// 清除所有的内存空间
void clear()
{
ACE_GUARD(_ACEMutex, ace_mon, *_Mutex);
if (_ChainList)
{
_ChainList->free();
_ChainList = 0;
_FreeNode = 0;
}
}
/**//// 初始化参数
void create(size_t blockSize, size_t blockCount, _ACEMutex* mutex = 0)
{
_BlockSize = blockSize;
_BlockCount = blockCount;
assert(_BlockCount >= 1);
assert(sizeof(CacheNode) <= _BlockSize);
if (_DeleteMutex && _Mutex)
delete _Mutex;
if (mutex != 0)
{
_Mutex = mutex;
_DeleteMutex = false;
}
else
{
_Mutex = new _ACEMutex();
_DeleteMutex = true;
}
}
/**//// 获取块的大小
size_t getBlockSize() const
{
return _BlockSize;
}
/**//// 获取连续分配的块的数目
size_t getBlockCount() const
{
return _BlockCount;
}
/**//// 分配一个块内存
void* alloc()
{
assert(_BlockCount >= 1);
assert(sizeof(CacheNode) <= _BlockSize);
assert(_Mutex != NULL);
ACE_GUARD_RETURN(_ACEMutex, ace_mon, *_Mutex, NULL);
if (_FreeNode == 0)
{
// 分配另一个数据链
CacheChain* newChain = CacheChain::create(_ChainList, _BlockSize, _BlockCount);
CacheNode* node = (CacheNode*)newChain->data();
// 定位到最后一个节点
(char*&)node += _BlockSize * (_BlockCount - 1);
// 建立连接关系
for (int i=(int)_BlockCount-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)
{
ACE_GUARD(_ACEMutex, ace_mon, *_Mutex);
if (block != 0)
{
CacheNode* node = (CacheNode*)block;
node->_Next = _FreeNode;
_FreeNode = node;
}
}
};
/**//**
对象池
在CachePool的基础上,增加了对象的构造和析构
为了更好扩充,没有采取继承而是包含的作法
*/
template<class T, class _ACEMutex>
class ObjectPool
{
protected:
typedef CachePool<_ACEMutex> _CachePool;
_CachePool _Pool;
public:
ObjectPool()
{
}
ObjectPool(size_t blockCount, _ACEMutex* mutex = 0)
{
_Pool.create(sizeof(T), blockCount, mutex);
}
/**//// 清除分配的内存
void clear()
{
_Pool.clear();
}
/**//// 初始化参数
void create(size_t blockCount, _ACEMutex* mutex = 0)
{
_Pool.create(sizeof(T), blockCount, mutex);
}
/**//// 获取连续分配的对象的数目
size_t getObjectCount() const
{
return _Pool.getBlockCount();
}
/**//// 创建对象的内存空间,但是没有进行构造,用户可以自行进行定制的构造
T* alloc()
{
void* obj = _Pool.alloc();
::new (obj) T(/**//* not args */); // 进行默认构造
return (T*)obj;
}
/**//// 释放对象
void free(T* obj)
{
if (obj != 0)
{
obj->~T();
_Pool.free(obj);
}
}
};
} // namespace om
#endif // OM_MEMPOOLT_H