服务器开发过程中,经常性的需要创建一块内存,但是在并发量高的情况下频繁创建删除,并不合适。所以需要一个对象池来管理常用的内存。
#include<queue>
#include<unordered_map>
#include <memory>
#include "CodeException.h"
class ObjectPool
{
const int _object_size;
std::queue<char*> _free_objects;
public:
ObjectPool(int objectSize):_object_size(objectSize){}
~ObjectPool() {
int iSize = _free_objects.size();
for (int i = 0; i < iSize; i++)
{
free(_free_objects.front());
}
}
inline char* Create() {
char* pObjectAddr = nullptr;
if (_free_objects.empty())
{
pObjectAddr = static_cast<char*>malloc(_object_size);
if (nullptr == pObjectAddr) throw CodeExceptionLog("can't malloc memory");
}
else
{
pObjectAddr = _free_objects.front();
_free_objects.pop();
}
return pObjectAddr;
}
inline void Release(char* pObjectAddr) {
if (nullptr == pObjectAddr) throw CodeExceptionLog("illegal args");
_free_objects.push(pObjectAddr);
}
};
typedef std::unordered_map<int, ObjectPool*> CMapObjectPool;
class ObjectAllocator
{
CMapObjectPool _map_object_pool;
private:
ObjectAllocator() = default;
ObjectAllocator(const ObjectAllocator&) = delete;
ObjectAllocator& operator=(const ObjectAllocator&) = delete;
public:
~ObjectAllocator() {
for (auto item : _map_object_pool)
{
delete item.second;
}
_map_object_pool.clear();
}
template<typename Type>
inline void Init() {
int objectSize = sizeof(Type);
_map_object_pool[objectSize] = new ObjectPool(objectSize);;
}
public:
static ObjectAllocator& getInstance() {
static ObjectAllocator _g_instance;
return _g_instance;
}
template<typename Type, typename ...Args>
inline Type* allocate(const Args&... args) {
ObjectPool* pObjectPool = FindObjectPool(sizeof(Type));
return new(pObjectPool->Create())Type(args...);
}
template<typename Type>
inline void deletor(Type* pType) {
if (nullptr == pType) throw CodeExceptionLog("illegal args");
ObjectPool* pObjectPool = FindObjectPool(sizeof(Type));
pType->~Type();
pObjectPool->Release(reinterpret_cast<char*>(pType));
}
private:
inline ObjectPool* FindObjectPool(int objectSize) {
auto ite = _map_object_pool.find(objectSize);
if (_map_object_pool.end() == ite) throw CodeExceptionLog("illegal args");
return ite->second;
}
};