内存池
1. 内存池设计
1.1 目的
在给定的内存buffer上建立内存管理机制,根据用户需求从该buffer上分配内存或者将已经分配的内存释放回buffer中。
1.2 要求
尽量减少内存碎片,平均效率高于C语言的malloc和free。
1.3 设计思路
- 一个存储全部内存的容器
- 一个存储正在使用的内存的容器
- 一个存储未被使用的容器
实现
#ifndef TESTJSON_MEMORYPOOL_HPP
#define TESTJSON_MEMORYPOOL_HPP
#include <algorithm>
#include <functional>
#include <set>
#include <vector>
#include <queue>
#include <cstdlib>
#include <cxxabi.h>
template<typename T>
class MemoryPool
{
public:
MemoryPool();
MemoryPool(int max_size);
virtual ~MemoryPool();
T *alloc();
void release(T *obj);
void walkUsedMemList(std::function<void(T *)> func);
private:
static int ALLOC_STEP;
int mMaxSize;
int mCurrentSize;
std::queue<T *> mFreeMemList;
std::set<T *> mUsedMemList;
int newMemList(int size);
};
template<class T>
int MemoryPool<T>::ALLOC_STEP = 20;
template<class T>
MemoryPool<T>::MemoryPool()
{
this->mCurrentSize = 0;
this->mMaxSize = 0;
this->newMemList(ALLOC_STEP);
}
template<class T>
MemoryPool<T>::MemoryPool(int max_size)
{
this->mCurrentSize = 0;
this->mMaxSize = max_size;
this->newMemList(ALLOC_STEP);
}
template<class T>
MemoryPool<T>::~MemoryPool()
{
for_each(mUsedMemList.begin(), mUsedMemList.end(), [&](T *mem)
{
free(mem);
});
int queue_size = mFreeMemList.size() ;
for (int i = 0; i < queue_size; ++i)
{
auto mem = mFreeMemList.front();
free(mem);
mFreeMemList.pop();
}
}
template<class T>
void MemoryPool<T>::walkUsedMemList(std::function<void(T *)> func)
{
for_each(mUsedMemList.begin(), mUsedMemList.end(), [&](T *mem)
{
func(mem);
});
}
template<class T>
int MemoryPool<T>::newMemList(int size)
{
if (this->mMaxSize > 0)
{
int left = this->mMaxSize - this->mCurrentSize;
if (left == 0)
return 0;
size = size < left ? size : left;
}
for (int i = 0; i < size; i++)
{
T *mem = (T *) malloc(sizeof(T));
if (!mem)
{
printf("malloc failed! total size : %d \n", mCurrentSize);
return 0;
}
mFreeMemList.push(mem);
}
this->mCurrentSize += size;
// ???
// printf("pool add objs : %s pool , total size : %d\n", abi::__cxa_demangle(typeid(T).name(), 0, 0, 0), mCurrentSize);
return size;
}
template<class T>
T *MemoryPool<T>::alloc()
{
if (mFreeMemList.empty())
{
if (newMemList(ALLOC_STEP) == 0)
{
return NULL;
}
}
T *obj = mFreeMemList.front();
mUsedMemList.insert(obj);
mFreeMemList.pop();
return obj;
}
template<typename T>
inline void MemoryPool<T>::release(T *obj)
{
if (mUsedMemList.erase(obj))
{
mFreeMemList.push(obj);
}
}
#endif //TESTJSON_MEMORYPOOL_HPP