用stl中的list分别存储使用的内存块和未使用的内存块,内存默认分为4个字节一块,如果设置过大,可能浪费内存,设置过小,可能影响性能
#include <Windows.h>
#include <iostream>
#include <list>
#include <stdio.h>
#include <tchar.h>
#define WM_ARRANGE (WM_USER+1)
using namespace std;
DWORD WINAPI MainThreadProc(LPVOID lpParam);
struct MemoryInfo
{
byte * MemoryAddress;
DWORD MemoryBlockNum;
bool operator < (const MemoryInfo& MI)
{
return MemoryAddress <MI.MemoryAddress;
}
};
class __declspec(dllexport) MemoryPool
{
private:
list<MemoryInfo> UsedMemory;
list<MemoryInfo> UnUsedMemory;
int i;
WORD MemoryBlockSize;
CRITICAL_SECTION g_cs;
DWORD ThreadID;
DWORD Arrange_Index;
DWORD ExtraNew;
void * StartAddress;
DWORD TotalBlockNum;
DWORD TotalNew;
public:
MemoryPool(DWORD Size,WORD MemoryBlockSize=4);
void* GetMemory(DWORD Size);
void FreeMemory(void * address);
void Arrage();
void Collect();
DWORD GetExtraNew();
~MemoryPool();
};
DWORD MemoryPool::GetExtraNew()
{
return ExtraNew;
}
MemoryPool::~MemoryPool()
{
delete[] StartAddress;
}
void MemoryPool::Collect()
{
memset(StartAddress,'\0',TotalBlockNum*MemoryBlockSize);
UnUsedMemory.clear();
UsedMemory.clear();
MemoryInfo MI;
MI.MemoryAddress=(byte *)StartAddress;
MI.MemoryBlockNum=TotalBlockNum;
UnUsedMemory.push_back(MI);
}
MemoryPool::MemoryPool(DWORD Size,WORD MemoryBlockSize)
{
MemoryInfo MI;
MI.MemoryBlockNum=Size/MemoryBlockSize+1;
TotalBlockNum=MI.MemoryBlockNum;
MI.MemoryAddress=new byte[MI.MemoryBlockNum*MemoryBlockSize];
StartAddress=MI.MemoryAddress;
UnUsedMemory.push_back(MI);
this->MemoryBlockSize=MemoryBlockSize;
CreateThread(NULL,0,MainThreadProc,this,0,&ThreadID);
Arrange_Index=MI.MemoryBlockNum/6;
InitializeCriticalSection(&g_cs);
cout<<"总内存块数:"<<MI.MemoryBlockNum<<endl;
ExtraNew=0;
TotalNew=0;
}
void * MemoryPool::GetMemory(DWORD Size)
{
TotalNew++;
EnterCriticalSection(&g_cs);
WORD NeedBlockNum=Size/MemoryBlockSize;
NeedBlockNum+=Size%MemoryBlockSize?1:0;
list<MemoryInfo>::iterator it_UnUsedMemory=UnUsedMemory.end();
do
{
it_UnUsedMemory--;
if (NeedBlockNum<=(it_UnUsedMemory->MemoryBlockNum))
{
MemoryInfo MI;
MI.MemoryAddress=it_UnUsedMemory->MemoryAddress;
printf("申请:地址:%x占有内存块数:%u\n",MI.MemoryAddress,NeedBlockNum);
it_UnUsedMemory->MemoryBlockNum-=NeedBlockNum;
it_UnUsedMemory->MemoryAddress=it_UnUsedMemory->MemoryAddress+NeedBlockNum*MemoryBlockSize;
printf("变了的地址为:%x\n",it_UnUsedMemory->MemoryAddress);
MI.MemoryBlockNum=NeedBlockNum;
UsedMemory.push_back(MI);
if (it_UnUsedMemory->MemoryBlockNum==0)
{
UnUsedMemory.erase(it_UnUsedMemory);
}
LeaveCriticalSection(&g_cs);
return MI.MemoryAddress;
}
} while (it_UnUsedMemory!=UnUsedMemory.begin());
LeaveCriticalSection(&g_cs);
cout<<"额外申请"<<endl;
byte* newMemory=new byte[Size];
PostThreadMessage(ThreadID,WM_ARRANGE,NULL,NULL);
ExtraNew++;
return newMemory;
}
void MemoryPool::FreeMemory(void * address)
{
bool IsInExtra=false;
list<MemoryInfo>::iterator it_UsedMemory=UsedMemory.begin();
MemoryInfo MI;
do
{
if (it_UsedMemory->MemoryAddress==address)
{
MI.MemoryAddress=(byte *)address;
MI.MemoryBlockNum=it_UsedMemory->MemoryBlockNum;
UnUsedMemory.push_back(MI);
memset(MI.MemoryAddress,'\0',MI.MemoryBlockNum*MemoryBlockSize);
// printf("地址:%x\n",it_UsedMemory->MemoryAddress);
UsedMemory.erase(it_UsedMemory);
IsInExtra=true;
break;
}
it_UsedMemory++;
} while (it_UsedMemory!=UsedMemory.end());
//cout<<"数量:"<<UnUsedMemory.size()<<endl;
if (UnUsedMemory.size()>=Arrange_Index)
{
PostThreadMessage(ThreadID,WM_ARRANGE,NULL,NULL);
}
if (!IsInExtra)
{
delete[] address;
}
}
void MemoryPool::Arrage()
{
EnterCriticalSection(&g_cs);
cout<<"开始整理........."<<endl;
UnUsedMemory.sort();
list<MemoryInfo>::iterator it_UnUsedMemory;
for (it_UnUsedMemory=UnUsedMemory.begin();it_UnUsedMemory!=UnUsedMemory.end();it_UnUsedMemory++)
{
printf("%x空余内存块数:%u\n",it_UnUsedMemory->MemoryAddress,it_UnUsedMemory->MemoryBlockNum);
}
it_UnUsedMemory=UnUsedMemory.begin();
do
{
byte * EndAddress=it_UnUsedMemory->MemoryAddress+(it_UnUsedMemory->MemoryBlockNum)*MemoryBlockSize;
// printf("Endaddress:%x\n",EndAddress);
it_UnUsedMemory++;
if (EndAddress==it_UnUsedMemory->MemoryAddress)
{
DWORD MN=it_UnUsedMemory->MemoryBlockNum;
UnUsedMemory.erase(it_UnUsedMemory--);
it_UnUsedMemory->MemoryBlockNum+=MN;
}
} while (it_UnUsedMemory!=UnUsedMemory.end());
for (it_UnUsedMemory=UnUsedMemory.begin();it_UnUsedMemory!=UnUsedMemory.end();it_UnUsedMemory++)
{
printf("整理结果:%x内存块:%u\n",it_UnUsedMemory->MemoryAddress,it_UnUsedMemory->MemoryBlockNum);
}
LeaveCriticalSection(&g_cs);
cout<<"整理完毕........."<<endl;
cout<<"额外申请次数:"<<ExtraNew<<endl;
cout<<"总申请次数:"<<TotalNew<<endl;
}
DWORD WINAPI MainThreadProc(LPVOID lpParam)
{
MSG msg;
MemoryPool *MP=(MemoryPool*)lpParam;
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
while(true)
{
if(GetMessage(&msg,0,0,0)) //get msg from message queue
{
switch(msg.message)
{
case WM_ARRANGE:
MP->Arrage();
break;
}
}
};
return 0;
}