Server - 内存管理(内存池实现)

一、新建空的控制台项目 命名为helloMemory,添加头文件wAlloc.h(还有一个文件wAlloc.cpp)、MemoryMgr.hpp

wAlloc.h代码

#ifndef _wAlloc_H_
#define _wAlloc_H_
void* operator new (size_t size);
void operator delete(void *p);
void* operator new[](size_t size);
void operator delete[](void *p);
void* wMallocMem(size_t size);
void  wFreeMem(void *p);
#endif//

MemoryMgr.hpp代码

#ifndef _MemoryMgr_hpp_
#define _MemoryMgr_hpp_
#define _MAX_MEMORYSIZE_ 1024
#include <malloc.h>
#include <assert.h>

#ifdef _DEBUG
#include <stdio.h>
    #define xPrintf(...)  printf(__VA_ARGS__)
#else
    #define xPrintf(...)
#endif //debug

class MemoryAlloc;
//内存块
class MemoryBlock
{
public:
	int nID;              //内存块编号
	int nRef;             //引用次数
	bool bPool;	          //是否在内存池中
	MemoryAlloc* pAlloc;  //所属内存块
	MemoryBlock* pNext;   //下一个可用单元
private:
	char c1NULL;           //预留
	char c2NULL;           //预留
	char c3NULL;           //预留
};

class MemoryAlloc
{
public:
	MemoryAlloc()
	{
		_pBuf = nullptr;
		_pHeader = nullptr;
		_nUitlSize = 0;
		_nUitlNum = 0;
	}
	~MemoryAlloc()
	{
		if (_pBuf)
		{
			free(_pBuf);
		}
	}

protected:
	//内存池首地址
	char* _pBuf;
	//头部内存单元
	MemoryBlock* _pHeader;
	//内存单元大小
	size_t _nUitlSize;
	//内存单元数量
	size_t _nUitlNum;
	
public:
	//初始化内存池
	void initMemory()
	{
		assert(nullptr == _pBuf);

		if (_pBuf)
			return;

		//申请内存池内存
		size_t bufSize = (_nUitlSize+sizeof(MemoryBlock))*_nUitlNum;
		size_t realSize = _nUitlSize+sizeof(MemoryBlock);
		//xPrintf("<nUitl = %d,realSize = %d,MemoryBlock=%d,sizeof(void*):%d>\n", _nUitlSize, realSize, sizeof(MemoryBlock), sizeof(void*));
		//转化为char*
		_pBuf = (char*)malloc(bufSize);

		//初始化内存池
		_pHeader = (MemoryBlock*)_pBuf;
		_pHeader->bPool = true;
		_pHeader->nID = 0;
		_pHeader->nRef = 0;
		_pHeader->pAlloc = this;
		_pHeader->pNext = nullptr;

		MemoryBlock* pHeaderTemp = _pHeader;
		for (size_t n = 1; n < _nUitlNum; n++)
		{
			MemoryBlock* pTemp = (MemoryBlock*)(_pBuf + (realSize*n));
			//xPrintf("_pBuf + (realSize*n):%x\n", _pBuf + (realSize*n));
			pTemp->bPool = true;
			pTemp->nID = n;
			pTemp->nRef = 0;
			pTemp->pAlloc = this;
			pHeaderTemp->pNext = pTemp;
			pHeaderTemp = pTemp;
		}
		pHeaderTemp->pNext = nullptr;
	}
	//申请内存
	void* wAllocMeMory(size_t size)
	{
		if (!_pBuf)
		{
			initMemory();
		}
		MemoryBlock* pReturn = nullptr;
		if (nullptr == _pHeader)
		{
			pReturn = (MemoryBlock*)malloc(size + sizeof(MemoryBlock));
			pReturn->bPool = false;
			pReturn->nID = -1;
			pReturn->nRef = 1;
			pReturn->pAlloc = nullptr;
			pReturn->pNext = nullptr;
			xPrintf("wAllocMem<alloc=%x,bPool = false,id=%d,size=%d>\n", pReturn, pReturn->nID, size);
		}
		else
		{
			pReturn = _pHeader;//交出去当前内存块
			_pHeader = _pHeader->pNext;//指向下一个内存块
			assert(0 == pReturn->nRef);//观察当前内存块是否被使用
			pReturn->nRef = 1;//将当前内存块引用计数为1
			xPrintf("wAllocMem<alloc=%x,bPool = true,id=%d,size=%d>\n", pReturn, pReturn->nID, size);
		}
		return (char*)pReturn+sizeof(MemoryBlock);
	}
	//释放内存
	void wFreeMemory(void* pMem)
	{
		char *pDat = (char*)pMem;
		MemoryBlock* pBlock = (MemoryBlock*)(pDat - sizeof(MemoryBlock));
		assert(1 == pBlock->nRef);
		if (--pBlock->nRef != 0)
		{
			return;
		}
		if (pBlock->bPool)
		{
			pBlock->pNext = _pHeader;//将此内存单元的下一个单元指向头部
			_pHeader = pBlock;//将此内存单元给头部
		}
		else
		{
			free(pBlock);
			return;
		}
	}

};
template<size_t nUitlSize,size_t nUitlNum>
class MemoryAlloctor : public MemoryAlloc
{
public:
	MemoryAlloctor()
	{
		const size_t n = sizeof(void*);
		_nUitlSize = (nUitlSize/n)*n + (_nUitlSize % n ? n : 0);
		_nUitlSize = nUitlSize;
		_nUitlNum = nUitlNum;
	}
};
//内存管理工具
class MemoryMgr
{
private:
	MemoryMgr()
	{
		initSzAlloc(0, 64, &_mem64);
		initSzAlloc(65, 128, &_mem128);
		initSzAlloc(129, 256, &_mem256);
		initSzAlloc(257,512 , &_mem512);
		initSzAlloc(512, 1024, &_mem1024);
	}
	~MemoryMgr()
	{

	}
private:
	void initSzAlloc(int nBegin,int nEnd,MemoryAlloc* pMemAlloc)
	{
		//初始化内存池映射数组
		for (int n = nBegin; n <= nEnd; n++)
		{
			_szAlloc[n] = pMemAlloc;
		}

	}
public:
	//单例模式
	static MemoryMgr& Instance()
	{
		static MemoryMgr mgr;
		return mgr;
	}
	 //申请内存
	void* wAllocMem(size_t size)
	{
		if (size <= _MAX_MEMORYSIZE_)
		{
			//如果申请的内存小于最大值的话 调用生成函数
			return _szAlloc[size]->wAllocMeMory(size);
		}
		else
		{
			MemoryBlock* pReturn = (MemoryBlock*)malloc(size + sizeof(MemoryBlock));
			pReturn->bPool = false;
			pReturn->nID = -1;
			pReturn->nRef = 1;
			pReturn->pAlloc = nullptr;
			pReturn->pNext = nullptr;
			xPrintf("wAllocMem<alloc=%x,bPool = false,id=%d,size=%d>\n",pReturn,pReturn->nID,size);
		    return ((char*)pReturn + sizeof(MemoryBlock));
		}
	}
	 //释放内存
	void wFreeMem(void* pMem)
	{
		MemoryBlock* pBlock = (MemoryBlock*)((char*)pMem - sizeof(MemoryBlock));
		xPrintf("wFreeMem<alloc=%x,bPool = true,id=%d>\n", pBlock, pBlock->nID);
		if (pBlock->bPool)
		{
			pBlock->pAlloc->wFreeMemory(pMem);
		}
		else
		{
			if (--pBlock->nRef == 0)
				free(pBlock);
		}
	}
	void addRef(void* pMem)
	{
		MemoryBlock* pBlock = (MemoryBlock*)((char*)pMem - sizeof(MemoryBlock));
		++pBlock->nRef;
	}

private:
	MemoryAlloctor<64,100>  _mem64;
	MemoryAlloctor<128, 100> _mem128;
	MemoryAlloctor<256, 100> _mem256;
	MemoryAlloctor<512, 100> _mem512;
	MemoryAlloctor<1024, 100> _mem1024;
	MemoryAlloc* _szAlloc[_MAX_MEMORYSIZE_ + 1];//内存池
};
#endif//_MemoryMgr_hpp_

二、添加cpp文件:wAlloc.cpp helloMemory.cpp

wAlloc.cpp代码:

#include "wAlloc.h"
#include"MemoryMgr.hpp"
void* operator new(size_t size)
{
	return MemoryMgr::Instance().wAllocMem(size);
}
void operator delete(void *p)
{
	MemoryMgr::Instance().wFreeMem(p);
}
void* operator new[](size_t size)
{
	return MemoryMgr::Instance().wAllocMem(size);
}
void operator delete[](void *p)
{
	MemoryMgr::Instance().wFreeMem(p);
}
void* wMallocMem(size_t size)
{
	return MemoryMgr::Instance().wAllocMem(size);
}
void  wFreeMem(void *p)
{
	MemoryMgr::Instance().wFreeMem(p);
}

helloMemory.cpp代码:

#include <iostream>
#include <stdlib.h>
#include "MemoryMgr.hpp"
int main(int argc,char** argv)
{
/*
	//1
	char* data1 = new char[128];
	///2
	char* data2 = new char;
	//3
	char*  data3 = new char[64];
	//delete1 2 3
	delete[] data1;
	delete data2;
	delete[] data3;
*/

	/*char *data60[120];
	for (size_t i = 0; i < 12; i++)
	{
		data60[i] = new char[60];
	}
	for (size_t i = 0; i < 12; i++)
	{
		delete data60[i];
	}
	char *data120[120];
	for (size_t i = 0; i < 12; i++)
	{
		data120[i] = new char[120];
	}
	for (size_t i = 0; i < 12; i++)
	{
		delete data120[i];
	}*/

	char *data[1200];
	for (size_t i = 0; i < 1200; i++)
	{
		data[i] = new char[i];
	}
	for (size_t i = 0; i < 1200; i++)
	{
		delete data[i];
	}

	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫忘输赢

莫忘输赢 - 收钱袋

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值