VC 内存池

用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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值