内存池

来源:互联网 发布:人工智能行业 编辑:程序博客网 时间:2024/05/16 06:58


MemoryBlock.h

#ifndef MEMORY_BLOCK#define MEMORY_BLOCKtypedef unsigned short USHORT;/////////////////////////////////////////////////////#include <iostream>#include <new>using namespace std;class  MemoryBlock{public:MemoryBlock(USHORT nTypes = 1, USHORT nUnitSize = 0); //nType:一个大块包含的内存单元个数。nUnitSize:内存单元字节数~MemoryBlock();static void* operator new(size_t, USHORT nTypes, USHORT nUnitSize);static void operator delete(void *p, size_t);//出现warning C4291static void my_new_handler();USHORT nSize;USHORT nFree;USHORT nFirst;USHORT nDummyAlign1;MemoryBlock* pNext;char aData[1];};/////////////////////////////////////////////////////#endif



MemoryBlock.cpp

#include "MemoryBlock.h"////////////////////////////////////////////////////////////////////////////////////////////////////////////////////MemoryBlock::MemoryBlock(USHORT nTypes, USHORT nUnitSize) : nSize(nTypes * nUnitSize), nFree(nTypes - 1), nFirst(1), pNext(NULL){char *pData = aData;for (USHORT i = 1; i < nTypes; i++){*(USHORT*)(pData) = i;pData += nUnitSize;}nSize = nTypes * nUnitSize;}/////////////////////////////////////////////////////////void MemoryBlock::my_new_handler(){cout << "内存池内存申请失败" << endl;throw bad_alloc();}/////////////////////////////////////////////////////////MemoryBlock::~MemoryBlock(){}/////////////////////////////////////////////////////////void* MemoryBlock::operator new(size_t, USHORT nTypes, USHORT nUnitSize){new_handler global_handler = set_new_handler(my_new_handler);//设置内存申请异常处理函数return ::operator new(sizeof(MemoryBlock) + nTypes * nUnitSize);//向系统申请内存set_new_handler(global_handler);}/////////////////////////////////////////////////////////void MemoryBlock::operator delete(void *p, size_t){::operator delete (p);}


MemoryBlock.cpp


#include "MemoryBlock.h"////////////////////////////////////////////////////////////////////////////////////////////////////////////////////MemoryBlock::MemoryBlock(USHORT nTypes, USHORT nUnitSize) : nSize(nTypes * nUnitSize), nFree(nTypes - 1), nFirst(1), pNext(NULL){char *pData = aData;for (USHORT i = 1; i < nTypes; i++){*(USHORT*)(pData) = i;pData += nUnitSize;}nSize = nTypes * nUnitSize;}/////////////////////////////////////////////////////////void MemoryBlock::my_new_handler(){cout << "内存池内存申请失败" << endl;throw bad_alloc();}/////////////////////////////////////////////////////////MemoryBlock::~MemoryBlock(){}/////////////////////////////////////////////////////////void* MemoryBlock::operator new(size_t, USHORT nTypes, USHORT nUnitSize){new_handler global_handler = set_new_handler(my_new_handler);//设置内存申请异常处理函数return ::operator new(sizeof(MemoryBlock) + nTypes * nUnitSize);//向系统申请内存set_new_handler(global_handler);}/////////////////////////////////////////////////////////void MemoryBlock::operator delete(void *p, size_t){::operator delete (p);}


MemoryPool.h


#ifndef MEMORY_POOL#define MEMORY_POOLtypedef unsigned short USHORT;typedef unsigned long ULONG;///////////////////////////////////////////////////////////#include"MemoryBlock.h"class MemoryPool{public://nUnitSize:内存单元大小,nInitSize:第一个内存块包含的内存单元个数,nGrowSize:非第一个内存块包含的内存单元个数MemoryPool(USHORT nUnitSize, USHORT nInitSize = 1024, USHORT nGrowSize = 256);~MemoryPool();void* Alloc();void Free(void* p);private:MemoryBlock*pBlock;USHORTnUnitSize;USHORTnInitSize;USHORTnGrowSize;};///////////////////////////////////////////////////////////#endif

MemoryPool.cpp


#include "MemoryPool.h"const USHORT MEMPOOL_ALIGNMENT=2;///////////////////////////////////////////////////////////MemoryPool::MemoryPool(USHORT _nUnitSize, USHORT _nInitSize, USHORT _nGrowSize) : pBlock(NULL), nInitSize(_nInitSize), nGrowSize(_nGrowSize){if (_nUnitSize > 4){nUnitSize = (_nUnitSize + (MEMPOOL_ALIGNMENT-1)) & ~(MEMPOOL_ALIGNMENT-1);}else if (_nUnitSize <= 2){nUnitSize = 2;}else{nUnitSize = 4;}}///////////////////////////////////////////////////////////void* MemoryPool::Alloc(){//第一次使用内存池if (!pBlock){ pBlock = new(nInitSize, nUnitSize) MemoryBlock(nInitSize, nUnitSize);return (void*)(pBlock->aData);}MemoryBlock* pMyBlock = pBlock;//寻找一个有空闲内存单元的块while (pMyBlock && !pMyBlock->nFree)pMyBlock = pMyBlock->pNext;//如果找到了有空闲内存单元的块,分配内存单元if(pMyBlock != NULL){char* pFree = pMyBlock->aData + (pMyBlock->nFirst * nUnitSize);pMyBlock->nFirst = *((USHORT*)pFree);(pMyBlock->nFree)--;return (void*)pFree;}//内存池中的内存单元用光了,再向系统申请一大块内存else{if (!nGrowSize){return NULL;}pMyBlock = new(nGrowSize, nUnitSize) MemoryBlock (nGrowSize, nUnitSize);if (!pMyBlock){return NULL;}//把大块内存加入到内存池的前面pMyBlock->pNext = pBlock;pBlock = pMyBlock;return (void*)(pMyBlock->aData);}}///////////////////////////////////////////////////////////void MemoryPool::Free(void* pFree){MemoryBlock* pMyBlock = pBlock;MemoryBlock* preBlock = pBlock;//确定pFree在哪个块中while ( ((ULONG)pMyBlock->aData > (ULONG)pFree) || ((ULONG)pFree >= ((ULONG)pMyBlock->aData + pMyBlock->nSize)) ){preBlock = pMyBlock;pMyBlock = pMyBlock->pNext;if (pMyBlock == NULL){return;}}(pMyBlock->nFree)++;//把刚刚回收的内存单元放在最前面*((USHORT*)pFree) = pMyBlock->nFirst;pMyBlock->nFirst = (USHORT)(((ULONG)pFree - (ULONG)(pBlock->aData)) / nUnitSize);//确定回收的内存单元的编号//判断是否需要把整个内存块返还给系统if (pMyBlock->nFree*nUnitSize == pMyBlock->nSize){//是否是第一个内存块if (preBlock == pMyBlock){pBlock = pMyBlock->pNext;}else{preBlock->pNext = pMyBlock->pNext;}delete pMyBlock;}}///////////////////////////////////////////////////////////MemoryPool::~MemoryPool(){MemoryBlock* NextBlock = pBlock;while (pBlock){NextBlock = pBlock->pNext;delete pBlock;pBlock = NextBlock;}}

hight_time.h

#include <windows.h>class High_Timer{private:_LARGE_INTEGER TimeStart;_LARGE_INTEGER TimeEnd;public:void Start();//计时开始void End();//计时结束 double Timer();//返回时差};////////////////////////////////////////////////////////#endif

hight_time.cpp

#include "High_Time.h"//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void High_Timer::Start(){    QueryPerformanceCounter(&TimeStart);    //计时开始}void High_Timer::End(){    QueryPerformanceCounter(&TimeEnd);    //计时结束}///////////////////////////////////////////////////////////double High_Timer::Timer(){    static double Freq;//计时器频率    static bool getfreq = false;    if (!getfreq)//获得计时器频率,只运行一次    {        LARGE_INTEGER f;        if (QueryPerformanceFrequency(&f))            Freq = f.QuadPart;        else            throw "无法获得定时器频率";        getfreq = true;    }    return (TimeEnd.QuadPart - TimeStart.QuadPart) / Freq;}

test


#include "MemoryPool.h"#include "High_Time.h"intmain(){int* p[3000];int i;High_Timer time_Test;////////////////////////////////////////////////////////////////////////////////////////time_Test.Start();for (i = 0; i != 3000; i++){p[i] = new int;}for (i = 0; i != 3000; i++){delete p[i];}time_Test.End();cout << "no using MemoryPool:" << time_Test.Timer() << endl;////////////////////////////////////////////////////////////////////////////////////////time_Test.Start();MemoryPool Mp_test(sizeof(int), 1024, 512);for (i = 0; i != 3000; i++){p[i] = (int*)Mp_test.Alloc();}for (i = 0; i != 3000; i++){Mp_test.Free(p[i]);}time_Test.End();cout << "using MemoryPool:" << time_Test.Timer() << endl;system("pause");return 0;}


原创粉丝点击