#pragma once
#include<vector>
template<class T>
class ObjectPool
{
protected:
struct Node
{
void* _memory;// 內存塊
Node* _next; //指向下一塊節點的指針
size_t _objectNum;//統計內存對象的個數
Node(size_t objectNum)
:_objectNum(objectNum)
,_next(NULL)
{
_memory=malloc(_iteamSize*_objectNum);
}
};
size_t _countIn;//當前節點已用的個數
Node* _frist;
Node* _last;
size_t _maxNum; //節點申請內存塊最大大小
static size_t _iteamSize;//單個對象的大小
T* _lastDelete;
public:
static size_t initIteam()
{
if(sizeof(T)>=sizeof(void*))
return sizeof(T);
else
return sizeof(void*);
}
ObjectPool(size_t initNum=32,size_t maxNum=10000)
:_countIn(0)
,_maxNum(maxNum)
,_lastDelete(NULL)
{
if(initNum>maxNum)
initNum=maxNum;
_frist=new Node(initNum);
_last=_frist;
}
T* New()
{
if(_lastDelete)
{
T* obj=_lastDelete;
_lastDelete=*((T**)_lastDelete);
return new (obj)T();//new的定位表達式
}
else //沒有釋放的內存對象
{
if(_countIn>=_last->_objectNum)
AllocateNewNode();
T* obj=(T*)((char*)_last->_memory+_countIn*_iteamSize);
_countIn++;
return new (obj)T(); //obj是地址,T是類型
}
}
void AllocateNewNode()
{
size_t objectNum=_last->_objectNum*2;
if(objectNum>_maxNum)
objectNum=_maxNum;
_last->_next=new Node(objectNum);
_last=_last->_next;
_countIn=0;
}
void Delete(T* ptr)
{
if(ptr)
{
*((T**)ptr)=_lastDelete;
_lastDelete=ptr;
}
}
void Destory()
{
Node* cur=_frist;
while(cur)
{
Node* del=cur;
cur=cur->_next;
delete del;
}
_countIn=0;
_frist=_last=NULL;
}
~ObjectPool()
{
Destory();
}
};
template<class T> //靜態的成員變量必須在類外進行初始化
size_t ObjectPool<T>::_iteamSize =ObjectPool<T>::initIteam ();
// 測試內存對象池的常規使用和內存對象的重複使用
void TestObjectPool()
{
vector<string*> v;
ObjectPool<string> pool;
for (size_t i = 0; i < 32; ++i)
{
v.push_back(pool.New());
printf("Pool New [%d]: %p\n", i, v.back());
}
while (!v.empty())
{
pool.Delete(v.back());
v.pop_back();
}
for (size_t i = 0; i < 32; ++i)
{
v.push_back(pool.New());
printf("Pool New [%d]: %p\n", i, v.back());
}
v.push_back(pool.New());
printf("Pool New : %p\n", v.back());
}
#include <Windows.h>
// 針對當前的內存對象池進行簡單的性能測試
void TestObjectPoolOP()
{
size_t begin , end;
vector<string*> v;
const size_t N = 10000;
v.reserve(N);
cout<<"pool new/delete==============================="<<endl;
// 反覆申請釋放5次
begin = GetTickCount();
ObjectPool<string> pool;
for (size_t i = 0; i < N; ++i)
{
v.push_back(pool.New());
}
while (!v.empty())
{
pool.Delete(v.back());
v.pop_back();
}
for (size_t i = 0; i < N; ++i)
{
v.push_back(pool.New());
}
while (!v.empty())
{
pool.Delete(v.back());
v.pop_back();
}
for (size_t i = 0; i < N; ++i)
{
v.push_back(pool.New());
}
while (!v.empty())
{
pool.Delete(v.back());
v.pop_back();
}
for (size_t i = 0; i < N; ++i)
{
v.push_back(pool.New());
}
while (!v.empty())
{
pool.Delete(v.back());
v.pop_back();
}
for (size_t i = 0; i < N; ++i)
{
v.push_back(pool.New());
}
while (!v.empty())
{
pool.Delete(v.back());
v.pop_back();
}
end = GetTickCount();
cout<<"Pool:"<<end - begin<<endl;
cout<<"new/delete==============================="<<endl;
begin = GetTickCount();
for (size_t i = 0; i < N; ++i)
{
v.push_back(new string);
}
while (!v.empty())
{
delete v.back();
v.pop_back();
}
for (size_t i = 0; i < N; ++i)
{
v.push_back(new string);
}
while (!v.empty())
{
delete v.back();
v.pop_back();
}
for (size_t i = 0; i < N; ++i)
{
v.push_back(new string);
}
while (!v.empty())
{
delete v.back();
v.pop_back();
}
for (size_t i = 0; i < N; ++i)
{
v.push_back(new string);
}
while (!v.empty())
{
delete v.back();
v.pop_back();
}
for (size_t i = 0; i < N; ++i)
{
v.push_back(new string);
}
while (!v.empty())
{
delete v.back();
v.pop_back();
}
end = GetTickCount();
cout<<"new/delete:"<<end - begin<<endl;
}
內存池
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.