内存池,大家观摩下,最好留下尊珍贵的建议!

版主大哥 2014-04-10 04:13:15

/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
#ifndef __MEMPOOL_H__
#define __MEMPOOL_H__

#include <assert.h>

using namespace std;

enum MemType
{
Mem_0_Bit_Size = 0,
Mem_16_Bit_Size = 16,
Mem_32_Bit_Size = 32,
Mem_64_Bit_Size = 64,
Mem_128_Bit_Size = 128,
Mem_256_Bit_Size = 256,
Mem_512_Bit_Size = 512,
Mem_1k_Bit_Size = 1024,
Mem_2k_Bit_Size = 2*1024,
Mem_4k_Bit_Size = 4*1024,
Mem_8k_Bit_Size = 8*1024,
Mem_16k_Bit_Size = 16*1024,
Mem_32k_Bit_Size = 32*1024,
Mem_64k_Bit_Size = 64*1024,
Mem_128k_Bit_Size = 128*1024,
Mem_256k_Bit_Size = 256*1024,
Mem_512k_Bit_Size = 512*1024,
Mem_1m_Bit_Size = 1024*1024,
};


struct MemBlock
{
MemBlock(int nMenLen) : m_nMemLen(nMenLen),m_pPreBlock(NULL),m_pNextBlock(NULL){}
int m_nMemLen;
MemBlock* m_pPreBlock;
MemBlock* m_pNextBlock;
};

class MemTypeAllocator
{
public:
MemTypeAllocator(int nBlockType);
~MemTypeAllocator();
void* AllocMemory();
void FreeMemory(void* pFreeMemory);
int GetTotalBlockCount();
int GetFreeBlockCount();
int GetBlockType();
void DumpNode();
private:
static const int BlockMax = 20;
int m_nBlockType;
long m_nTotalBlockNum;
long m_nFreeBlockNum;
MemBlock* m_pBeginBlock;
MemBlock* m_pEndBlock;
};
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
MemTypeAllocator::MemTypeAllocator(int nBlockType) : m_nBlockType(nBlockType),m_nTotalBlockNum(0),m_nFreeBlockNum(0),m_pBeginBlock(NULL),m_pEndBlock(NULL)
{

}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
MemTypeAllocator::~MemTypeAllocator()
{

}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
void* MemTypeAllocator::AllocMemory()
{
void* pRet = NULL;

if (m_pEndBlock != NULL)
{
assert(m_pEndBlock->m_pNextBlock == NULL);

MemBlock* pTond = m_pEndBlock;

pRet = (char*)m_pEndBlock + sizeof(MemBlock);

m_pEndBlock = m_pEndBlock->m_pPreBlock;

if (m_pEndBlock != NULL)
{
m_pEndBlock->m_pNextBlock = pTond->m_pNextBlock;
}
else
{
m_pBeginBlock = NULL;
}
pTond->m_pPreBlock = NULL;

m_nFreeBlockNum--;
}
else
{
void* pMemory = malloc(m_nBlockType + sizeof(MemBlock));

MemBlock* pNewBlock = (MemBlock*)pMemory;

assert(pNewBlock != NULL);

pNewBlock->m_nMemLen = m_nBlockType;

pNewBlock->m_pNextBlock = NULL;

pNewBlock->m_pPreBlock = NULL;

pRet = (char*)pNewBlock + sizeof(MemBlock);

m_nTotalBlockNum++;
}
return pRet;
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
void MemTypeAllocator::FreeMemory(void* pFreeMemory)
{
assert(pFreeMemory != NULL);

if (pFreeMemory == NULL)
{
return;
}
MemBlock* pMemBlock = (MemBlock*)((char*)pFreeMemory - sizeof(MemBlock));

if (m_nFreeBlockNum > BlockMax)
{
free(pMemBlock);

pMemBlock = NULL;

m_nTotalBlockNum--;
}
else
{
if (NULL == m_pBeginBlock)
{
m_pBeginBlock = pMemBlock;

m_pEndBlock = pMemBlock;
}
else
{
pMemBlock->m_pNextBlock = m_pBeginBlock;

m_pBeginBlock->m_pPreBlock = pMemBlock;

m_pBeginBlock = pMemBlock;
}
m_nFreeBlockNum++;
}
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
int MemTypeAllocator::GetTotalBlockCount()
{
return m_nTotalBlockNum;
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
int MemTypeAllocator::GetFreeBlockCount()
{
return m_nFreeBlockNum;
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
int MemTypeAllocator::GetBlockType()
{
return m_nBlockType;
}
/************************************************************************
* Function : NA
* Author : xihu
* Input :
* Output :
* Info : 2014/04/03
************************************************************************/
void MemTypeAllocator::DumpNode()
{
MemBlock* pTond = m_pBeginBlock;

while (pTond)
{
TRACE("Node:%p->",pTond);

pTond = pTond->m_pNextBlock;
}
TRACE("NULL\n");

TRACE("pBegin : %p pEnd:%p\n",m_pBeginBlock,m_pEndBlock);
}



#endif
...全文
571 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
monekia 2015-10-17
  • 打赏
  • 举报
回复
测试代码如下:
struct MyStruct
	{
		char tt[128];
	};
	const int arrsize = 30;
	const int looptime = 100000;
	CMemoryPool<MyStruct>test;
	
	MemoryPool mempool;

	mempool.InitMemoryPool();

	clock_t beg, end;
	char buf[64];
	int ncount = 0;
	MyStruct * arr[arrsize] = { 0, };

	test.Init(100, 100);
	beg = clock();
	for (int i = 0; i < looptime;i++)
	{
		for (int j = 0;j < arrsize;j++)
		{
			arr[j] = test.Alloc();
			if (NULL == arr[j])
				ncount++;
		}
		for (int j = 0;j < arrsize;j++)
		{
			test.Free(arr[j]);
		}
	}
	end = clock();
	
	sprintf_s(buf, "used time %f s alloc createbandtimes:%d\n", 1.0*(end - beg) / CLOCKS_PER_SEC,test.GetCreateBandTimes());
	OutputDebugString(buf);

	beg = clock();
	for (int i = 0; i < looptime;i++)
	{
		for (int j = 0;j < arrsize;j++)
		{
			//arr[j] = new MyStruct;
			arr[j] = (MyStruct*)malloc(sizeof(MyStruct));
		}
		for (int j = 0;j < arrsize;j++)
		{
			//delete arr[j];
			free(arr[j]);
		}
	}
	end = clock();
	sprintf_s(buf, "used time %f s\n", 1.0*(end - beg) / CLOCKS_PER_SEC);
	OutputDebugString(buf);

	beg = clock();
	for (int i = 0; i < looptime;i++)
	{
		for (int j = 0;j < arrsize;j++)
		{
			arr[j] = (MyStruct*)mempool.Malloc(sizeof(MyStruct));
		}
		for (int j = 0;j < arrsize;j++)
		{
			mempool.Free(arr[j]);
		}
	}
	end = clock();
	sprintf_s(buf, "used time %f s\n", 1.0*(end - beg) / CLOCKS_PER_SEC);
	OutputDebugString(buf);
monekia 2015-10-17
  • 打赏
  • 举报
回复
为何我测试时 耗时不比系统的快 同时还有内存泄露呢??.
Pump天天学习 2014-04-11
  • 打赏
  • 举报
回复
顶楼主 有空学习下
lis2012 2014-04-11
  • 打赏
  • 举报
回复
向lz学习了
yiyefangzhou24 2014-04-11
  • 打赏
  • 举报
回复
intel有一个内存池的示例性代码,我觉得写的非常好
版主大哥 2014-04-11
  • 打赏
  • 举报
回复
多线程中加了锁就慢了,不过还是比malloc快 我就在想,要么在锁粒度上做文章,要么干脆不用锁
menzi11 2014-04-11
  • 打赏
  • 举报
回复
多线程内存池必lockfree
AresEntice 2014-04-11
  • 打赏
  • 举报
回复
引用 16 楼 yiyefangzhou24 的回复:
intel有一个内存池的示例性代码,我觉得写的非常好
请给个链接,谢谢!
mLee79 2014-04-10
  • 打赏
  • 举报
回复
内存池这种还是要 lock-free 下的, 加了锁就不好意思了..
q598162221 2014-04-10
  • 打赏
  • 举报
回复
定长内存池有BOOST 的POOL 不定长内存池可以用apache的apr中的内存池
版主大哥 2014-04-10
  • 打赏
  • 举报
回复
在线程安全上,不知道还有其他更好的方法不? 想过让每个线程一个线程池.其他线程使用另外线程的内存,释放的时候以控制权的方式,交付给申请的线程释放....
版主大哥 2014-04-10
  • 打赏
  • 举报
回复
引用 6 楼 ADF1230 的回复:
enum MemType{} //修改成const int 列表吧 //static const int MemSizeList[] = {}; static const int MemTypeMax = 17; //魔数 //static const int MemTypeMax = sizeof(MemSizeList) / sizeof(int)
记下了,非常感谢
点不亮的黑色 2014-04-10
  • 打赏
  • 举报
回复
神-气 2014-04-10
  • 打赏
  • 举报
回复
另,既然用C++11,那为什么不多用点特性呢 ~
神-气 2014-04-10
  • 打赏
  • 举报
回复
enum MemType{} //修改成const int 列表吧 //static const int MemSizeList[] = {}; static const int MemTypeMax = 17; //魔数 //static const int MemTypeMax = sizeof(MemSizeList) / sizeof(int)
lm_whales 2014-04-10
  • 打赏
  • 举报
回复
版主大哥 2014-04-10
  • 打赏
  • 举报
回复
单线程与malloc的测试数据: 内存分配1W次: 大小 100(byte) 1000(byte) 5000(byte) 10000(byte) 系统 31 毫秒 31 毫秒 31 毫秒 31 毫秒 内存池 0 毫秒 0 毫秒 0 毫秒 0 毫秒 内存分配10W次: 大小 100(byte) 1000(byte) 5000(byte) 10000(byte) 系统 62 毫秒 266 毫秒 328 毫秒 531 毫秒 内存池 47 毫秒 47 毫秒 47 毫秒 47 毫秒 内存分配100W次: 大小 100(byte) 1000(byte) 5000(byte) 10000(byte) 系统 800 毫秒 2400 毫秒 2040 毫秒 5321 毫秒 内存池 296 毫秒 296 毫秒 296 毫秒 296 毫秒 内存分配1000W次: 大小 100(byte) 1000(byte) 5000(byte) 10000(byte) 系统 7353 毫秒 24929 毫秒 20436 毫秒 52557 毫秒 内存池 2933 毫秒 2933 毫秒 2933 毫秒 2933 毫秒 多线程的测试数据没记下来...
版主大哥 2014-04-10
  • 打赏
  • 举报
回复


unsigned int WINAPI WorkThread(void* pParam)
{
	int nRet = -1;

	MemoryPool* pMemoryPool = (MemoryPool*)pParam;

	
	int nNum = 10000;

	int nSize = 1000;

	int nBeginTick = GetTickCount();

	int nEndTick = 0;

	void* pRet[100]; 

	char* ptrArry = NULL;

	//10W    1435       7675     203  796
	for (int i = 0;i < nNum;i++)	
	{
		/*
		ptrArry = (char*)malloc(nSize);
		free(ptrArry);
		*/

		/*
		ptrArry = (char*)pMemoryPool->Malloc(nSize);
		pMemoryPool->Free(ptrArry);
		*/
		/*
		for (int j = 0; j < 30;j++)
		{
			pRet[j] = malloc(nSize);
		}
		for (int j = 0; j < 30;j++)
		{
			free(pRet[j]);
		}
		*/
		
		for (int j = 0; j < 30;j++)
		{
			pRet[j] = pMemoryPool->Malloc(nSize);
		}
		for (int j = 0; j < 30;j++)
		{
			pMemoryPool->Free(pRet[j]);
		}
		
		//mempool.DunmMemoryPool();
	}

	nEndTick = GetTickCount() - nBeginTick;

	TRACE("UserTime : %d\n",nEndTick);
	
	//pMemoryPool->DunmMemoryPool();

	return nRet;
}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	HMODULE hModule = ::GetModuleHandle(NULL);

	if (hModule != NULL)
	{
		// initialize MFC and print and error on failure
		if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
		{
			// TODO: change error code to suit your needs
			_tprintf(_T("Fatal Error: MFC initialization failed\n"));
			nRetCode = 1;
		}
		else
		{
			// TODO: code your application's behavior here.
		}
	}
	else
	{
		// TODO: change error code to suit your needs
		_tprintf(_T("Fatal Error: GetModuleHandle failed\n"));
		nRetCode = 1;
	}

	MemoryPool mempool;

	mempool.InitMemoryPool();


	unsigned int dwThreadID = 0;

	for (int n = 0;n < 4;n++)
	{
		_beginthreadex(NULL,0,WorkThread,&mempool,0,&dwThreadID);
	}

	while(1)
	{

	}

	return nRetCode;
}

版主大哥 2014-04-10
  • 打赏
  • 举报
回复

class MemoryPool
{
public:
	MemoryPool(){};
	~MemoryPool(){};

	void InitMemoryPool();
	void UnInitMemoryPool();

	void* Malloc(int nSize);
	void Free(void* pMemory);

	long GetTotalMemorySize();
	long GetFreeMemorySize();

	int GetTotalBlockCountForType(int nType);
	int GetFreeBlockCountForType(int nType);

	int GetBlockTypeCount();

	void DunmMemoryPool();

protected:
	int FitSize(int nSize);

	int FindElement(int nType);

	int FindType(int nElement);

private:
	static const int			MemTypeMax = 17;

	MemTypeAllocator*			m_arrayAllocator[MemTypeMax]; 

	CRITICAL_SECTION			m_cs;
};
/************************************************************************
* Function : NA
* Author   : xihu
* Input    : 
* Output   : 
* Info     : 2014/04/03
************************************************************************/
int MemoryPool::FindElement(int nType)
{
	int nRet = -1;

	if (nType > 0 && nType <= Mem_1m_Bit_Size)
	{
		nRet = (int)(log10(nType*1.0)/log10(2.0) - 4);
	}
	return nRet;
}
/************************************************************************
* Function : NA
* Author   : xihu
* Input    : 
* Output   : 
* Info     : 2014/04/03
************************************************************************/
int MemoryPool::FindType(int nElement)
{
	int nRet = -1;

	if (nElement >= 0 && nElement < MemTypeMax)
	{
		nRet = (int)pow(2.0,nElement + 4);
	}
	return nRet;
}
/************************************************************************
* Function : NA
* Author   : xihu
* Input    : 
* Output   : 
* Info     : 2014/04/03
************************************************************************/
void MemoryPool::InitMemoryPool()
{
	InitializeCriticalSection(&m_cs);

	for (int i = 0;i < MemTypeMax;i++)
	{
		int nType = FindType(i);

		m_arrayAllocator[i] = new MemTypeAllocator(nType);
	}
}
/************************************************************************
* Function : NA
* Author   : xihu
* Input    : 
* Output   : 
* Info     : 2014/04/03
************************************************************************/
void MemoryPool::UnInitMemoryPool()
{
	DeleteCriticalSection(&m_cs);

	for (int i = 0;i < MemTypeMax;i++)
	{
		delete m_arrayAllocator[i];

		m_arrayAllocator[i] = NULL;
	}
}

/************************************************************************
* Function : NA
* Author   : xihu
* Input    : 
* Output   : 
* Info     : 2014/04/03
************************************************************************/
int MemoryPool::FitSize(int nSize)
{
	int nRet = -1;

	if (nSize <= 0)
	{
		return nRet;
	}
	else if (nSize >0 && nSize <= Mem_16_Bit_Size)
	{ 
		nRet = Mem_16_Bit_Size;
	}
	else if (nSize <= Mem_32_Bit_Size) 
	{ 
		nRet = Mem_32_Bit_Size;
	}
	else if (nSize <= Mem_64_Bit_Size) 
	{ 
		nRet = Mem_64_Bit_Size; 
	}
	else if (nSize <= Mem_128_Bit_Size) 
	{ 
		nRet = Mem_128_Bit_Size; 
	}
	else if (nSize <= Mem_256_Bit_Size) 
	{ 
		nRet = Mem_256_Bit_Size; 
	}
	else if (nSize <= Mem_512_Bit_Size) 
	{ 
		nRet = Mem_512_Bit_Size; 
	}
	else if (nSize <= Mem_1k_Bit_Size) 
	{ 
		nRet = Mem_1k_Bit_Size; 
	}
	else if (nSize <= Mem_2k_Bit_Size) 
	{ 
		nRet = Mem_2k_Bit_Size; 
	} 
	else if (nSize <= Mem_4k_Bit_Size) 
	{ 
		nRet = Mem_4k_Bit_Size; 
	} 
	else if (nSize <= Mem_8k_Bit_Size) 
	{ 
		nRet = Mem_8k_Bit_Size; 
	} 
	else if (nSize <= Mem_16k_Bit_Size) 
	{  
		nRet = Mem_16k_Bit_Size;
	} 
	else if (nSize <= Mem_32k_Bit_Size)
	{  
		nRet = Mem_32k_Bit_Size;
	} 
	else if (nSize <= Mem_64k_Bit_Size)
	{  
		nRet = Mem_64k_Bit_Size;
	} 
	else if (nSize <= Mem_128k_Bit_Size)
	{  
		nRet = Mem_128k_Bit_Size;
	} 
	else if (nSize <= Mem_256k_Bit_Size)
	{  
		nRet = Mem_256k_Bit_Size;
	} 
	else if (nSize <= Mem_512k_Bit_Size) 
	{ 
		nRet = Mem_512k_Bit_Size; 
	} 
	else if (nSize <= Mem_1m_Bit_Size) 
	{ 
		nRet = Mem_1m_Bit_Size;
	} 
	else
	{  
		//如果申请大于1M的内存直接申请
		//....
	}
	return nRet;
}
/************************************************************************
* Function : NA
* Author   : xihu
* Input    : 
* Output   : 
* Info     : 2014/04/03
************************************************************************/
void* MemoryPool::Malloc(int nSize)
{
	void* pRet = NULL;

	int nType = FitSize(nSize);

	if (nType > 0)
	{
		int nElement = FindElement(nType);

		if (nElement > 0)
		{
			EnterCriticalSection(&m_cs);

			pRet = m_arrayAllocator[nElement]->AllocMemory();

			LeaveCriticalSection(&m_cs);
		}
		else
		{
			assert(0);
		}
	}
	else
	{
		void* pTond = malloc(nSize + sizeof(MemBlock));

		assert(pTond != NULL);

		*(int*)pTond = -1;	//自行分配内存

		pRet = (char*)pTond + sizeof(MemBlock);
	}
	return pRet;
}
/************************************************************************
* Function : NA
* Author   : xihu
* Input    : 
* Output   : 
* Info     : 2014/04/03
************************************************************************/
void MemoryPool::Free(void* pMemory)
{
	if (pMemory == NULL)
	{
		return;
	}
	int* pType = (int*)((char*)pMemory - sizeof(MemBlock));

	assert(pType != NULL);

	int nElement = FindElement(*pType);

	if (nElement >= 0)
	{
		EnterCriticalSection(&m_cs);

		m_arrayAllocator[nElement]->FreeMemory(pMemory);

		LeaveCriticalSection(&m_cs);
	}
	else
	{
		void* pTond = (char*)pMemory - sizeof(MemBlock);

		free(pTond);
	}
	return;
}
/************************************************************************
* Function : NA
* Author   : xihu
* Input    : 
* Output   : 
* Info     : 2014/04/03
************************************************************************/
long MemoryPool::GetTotalMemorySize()
{
	long lRet = -1;

	for (int i = 0;i < MemTypeMax;i++)
	{
		lRet += m_arrayAllocator[i]->GetTotalBlockCount()*m_arrayAllocator[i]->GetBlockType();
	}
	return lRet;
}
/************************************************************************
* Function : NA
* Author   : xihu
* Input    : 
* Output   : 
* Info     : 2014/04/03
************************************************************************/
long MemoryPool::GetFreeMemorySize()
{
	long lRet = -1;

	for (int i = 0;i < MemTypeMax;i++)
	{
		lRet += m_arrayAllocator[i]->GetFreeBlockCount()*m_arrayAllocator[i]->GetBlockType();
	}
	return lRet;
}
/************************************************************************
* Function : NA
* Author   : xihu
* Input    : 
* Output   : 
* Info     : 2014/04/03
************************************************************************/
int MemoryPool::GetTotalBlockCountForType(int nType)
{
	int nRet = -1;

	int nElement = FindElement(nType);

	if (nElement >= 0)
	{
		nRet = m_arrayAllocator[nElement]->GetTotalBlockCount();
	}
	return nRet;
}
/************************************************************************
* Function : NA
* Author   : xihu
* Input    : 
* Output   : 
* Info     : 2014/04/03
************************************************************************/
int MemoryPool::GetFreeBlockCountForType(int nType)
{
	int nRet = -1;
	
	int nElement = FindElement(nType);

	if (nElement >= 0)
	{
		nRet = m_arrayAllocator[nElement]->GetFreeBlockCount();
	}
	return nRet;
}
/************************************************************************
* Function : NA
* Author   : xihu
* Input    : 
* Output   : 
* Info     : 2014/04/03
************************************************************************/
int MemoryPool::GetBlockTypeCount()
{
	int nRet = -1;

	nRet = MemTypeMax;

	return nRet;
}
/************************************************************************
* Function : NA
* Author   : xihu
* Input    : 
* Output   : 
* Info     : 2014/04/03
************************************************************************/
void MemoryPool::DunmMemoryPool()
{
	for (int i = 0;i < MemTypeMax;i++)
	{
		m_arrayAllocator[i]->DumpNode();
	}
}

64,635

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧