【项目】内存池(对象池)

来源:互联网 发布:淘宝货源网 编辑:程序博客网 时间:2024/06/07 14:49

项目名称:内存池

环境:VS2010

内容:利用链表存数组的形式

实现目的:系统中的new和delete调用比较消耗资源,设计一个相对消耗较小的对象池

大致思想:一个链表指向空闲内存,分配就是取出一块来,改写链表,返回,释放就是放回到链表里面,并做好归并。注意做好标记和保护,避免二次释放,还可以花点力气在如何查找最适合大小的内存快的搜索上,减少内存碎片


这里假设申请了12个字节大小的空间释放了三个字节

最后一个释放的空间存空,倒数第二个存倒数第一个释放的地址,以此类推,直至没有释放的空间,这样做是为了方便再次分配

实现一个 BlockNode,每个 BlockNode用于分配固定大小的内存块,比如用于分配 32字节对象的固定内存分配器,之类的。这个固定内存分配器回收的时候,统一把先前向系统申请的内存块全部还给系统。
按照不同对象大小(8字节,16字节,32,64,128,256,512,1K。。。64K),构造十多个固定内存分配器,分配内存时根据内存大小查表,决定到底由哪个分配器负责

代码

#include <iostream>using namespace std;#include <vector>#include <string>template<class T>class ObjectPool{struct BlockNode {void* _memory;BlockNode* _next;size_t _objNum;BlockNode(size_t objNum):_objNum(objNum),_next(NULL){_memory=malloc(_itemSize*_objNum);}};protected:size_t _countIn;//当前节点用的计数BlockNode* _first;BlockNode* _last;size_t _maxNum;//节点申请内存块对象大小static size_t _itemSize;//单个对象大小T* _lastDelete;public:ObjectPool(size_t initNum=32,size_t maxNum=10000):_countIn(0),_maxNum(maxNum),_lastDelete(NULL){_first=_last=new BlockNode(initNum);}~ObjectPool(){_Destory();_countIn=0;_maxNum=0;_first=NULL;_last= NULL;_lastDelete=NULL;}T* New(){//1.优先申请以前释放过的空间//2.内存块里面申请//3.申请新的节点对象if(_lastDelete){T* obj=_lastDelete;_lastDelete=*((T**)_lastDelete);return new(obj)T;}if (_countIn>=_last->_objNum){size_t objNum=GetObjNum(_last->_objNum);_last->_next=new BlockNode(objNum);_last=_last->_next;_countIn=0;}T* obj1=new((T*)((char*)_last->_memory+_itemSize*_countIn))T();_countIn++;return obj1;}void Delete(T* ptr){if(ptr){*(T**)ptr=_lastDelete;_lastDelete=ptr;}}static size_t InitItemSize()//初始化单个对象{if(sizeof(T)<sizeof(void*)){return sizeof(void*);}else{return sizeof(T);}}size_t GetObjNum(size_t Oldsize)//下一个对象空间大小{size_t objsize=2*Oldsize;if(objsize>_maxNum){return _maxNum;}else{return objsize;}}void _Destory()//销毁函数{BlockNode* cur=_first;while (cur){BlockNode* del=cur;cur=cur->_next;free(del->_memory);del->_objNum=0;delete del;}}};template<class T>size_t ObjectPool<T>::_itemSize=ObjectPool<T>::InitItemSize();//静态对象类外进行赋值///////////////////////////////////////////////////////////// 测试内存对象池的常规使用和内存对象的重复使用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());}#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;}
与new、delete比较


未完,持续更新


0 0
原创粉丝点击