基本信息
源码名称:内存池管理 实例源码
源码大小:0.02M
文件格式:.zip
开发语言:C#
更新时间:2015-12-13
   友情提示:(无需注册或充值,赞助后即可获取资源下载链接)

     嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300

本次赞助数额为: 2 元 
   源码介绍


//#pragma once
//#include "stdafx.h"
#include <assert.h>
#include "MemPool.h"
#include "AutoLock.h"
#include <time.h>


CMemPool::CMemPool()
{
}

CMemPool::~CMemPool()
{
}

//释放所有闲置状态的内存池
void CMemPool::FreeIdleTrunk()
{
	for (int nIndex = 0;nIndex < MEMPOOL_MAX_COUNT;nIndex  )
	{
		CAutoLock lock(m_pMemPoolLock[nIndex]); 
		for (int i = 0;i < m_MemPoolTable[nIndex].GetSizeNode();i  )
		{
			MemPoolData *_MemPoolData = (MemPoolData *)m_MemPoolTable[nIndex].GetNodeFromIndex(i);
			if (ch_FLASE == _MemPoolData->chbIsMemTrunkUsed)
			{
				free(_MemPoolData);
			}
		}
		m_MemPoolTable[nIndex].FreeIdleTrunk();
	}
}

/*******************************************************
申请内存时先加上附加数据然后对其,始终从m_MemPoolTable[i]的第1个元素开始查找
当内存池列中元素没有达到上限时申请内存加入内存池,反之而直接申请原大小内存

当内存属性修改完毕后需做交换处理以保证前一部分元素未占用后一部分元素被占用
********************************************************/
void* CMemPool::MallocBuffer(size_t nSize)
{
	size_t nOldSize = nSize;
	//先加上管理内存池的数据结构空间然后再对齐
	nSize  = ch_SIZE;   
	nSize = APR_ALIGN(nSize,MEMPOOL_ALIGN);
	//超过内存池设定最大长度则直接调用系统函数申请原长度
	if (nSize > MEMPOOL_MAX)
	{
		return malloc(nOldSize);
	}

	void* pBuffer = NULL;
	//计算出内存池中的索引位置
	int ilockIndex = (int)nSize/MEMPOOL_ALIGN;
	if (ilockIndex < MEMPOOL_MAX_COUNT)
	{
		CAutoLock lock(m_pMemPoolLock[ilockIndex]);
		int iSizeNode = m_MemPoolTable[ilockIndex].GetSizeNode();
		//计算出内存池中的索引位置
		if (iSizeNode < 128)
		{
			//由于保证前N个元素空闲,每次只取第一个元素即可
		    if (iSizeNode > 0)
		    {
				MemPoolData *_MemPoolData = (MemPoolData *)m_MemPoolTable[ilockIndex].GetNodeFromIndex(0);
				if (ch_FLASE == _MemPoolData->chbIsMemTrunkUsed)
				{
					//当从内存池中取得数据后交换保证前N的元素为空闲
					_MemPoolData->chbIsMemTrunkUsed = ch_TRUE;
					pBuffer = reinterpret_cast<void*>(reinterpret_cast<int>(_MemPoolData)   ch_SIZE);
					int iIndexCurrentAry = m_MemPoolTable[ilockIndex].GetCurrentIndex();
					SwapPoolData(ilockIndex,0,iIndexCurrentAry);
					m_MemPoolTable[ilockIndex].SetCurrentIndex(--iIndexCurrentAry);
					return pBuffer;
				}
		    }
			
			//有可能是内存池列为空,也有可能已经用完,判断一次是否获取成功
			pBuffer  = malloc(nSize   ch_SIZE);
			MemPoolData *_MemPoolData = (MemPoolData*)pBuffer;
			_MemPoolData->chbIsMemTrunkUsed    = ch_TRUE;
			_MemPoolData->dwMemTrunkTicket     = 0;
			_MemPoolData->SetOutIndex(ilockIndex);
			_MemPoolData->SetInIndex(iSizeNode);
			m_MemPoolTable[ilockIndex].Add(pBuffer);
			pBuffer = reinterpret_cast<void*>(reinterpret_cast<int>(pBuffer)   ch_SIZE);
			return pBuffer;
		}
	}

	//如果内存池中获取内存失败
	pBuffer  = malloc(nOldSize);
	return pBuffer;
}

/*******************************************************
回收内存池先根据内存池起始地址往后ch_SIZE个字节,找到外部索引和内部索引
即找到该块内存属于内存池中m_MemPoolTable[MEMPOOL_MAX_COUNT]第几个元素
以及m_MemPoolTable[i]中的第几项,然后修改内存属性。

当内存属性修改完毕后需做交换处理以保证前一部分元素未占用后一部分元素被占用
********************************************************/
void CMemPool::FreeBuffer(void* pBuffer)
{ 
	int nInIndex = 0;
	//先查外部索引和内部索引
	MemPoolData *_MemPoolData = NULL;
	_MemPoolData = reinterpret_cast<MemPoolData *>(reinterpret_cast<int>(pBuffer) - ch_SIZE);
	int nOutIndex = _MemPoolData->GetOutIndex();
	if (nOutIndex < MEMPOOL_MAX_COUNT)
	{
		CAutoLock lock(m_pMemPoolLock[nOutIndex]);
		nInIndex  = _MemPoolData->GetInIndex();
		if (nOutIndex >= 0 && nInIndex < MEMPOOL_MAX)
		{
			//当还原回内存池后做交换处理保证前N个元素空闲
			_MemPoolData->chbIsMemTrunkUsed = ch_FLASE;
			_MemPoolData->dwMemTrunkTicket  =  time(0);
			int iSizeNode = m_MemPoolTable[nOutIndex].GetSizeNode();
			int iIndexCurrentAry = m_MemPoolTable[nOutIndex].GetCurrentIndex();
			if (iIndexCurrentAry < 0)
			{
				SwapPoolData(nOutIndex,0,nInIndex);
				m_MemPoolTable[nOutIndex].SetCurrentIndex(0);
			}
			else
			{
				iIndexCurrentAry  ;
				int iSizeNode = m_MemPoolTable[nOutIndex].GetSizeNode();
				iIndexCurrentAry = iIndexCurrentAry==iSizeNode?iIndexCurrentAry-1:iIndexCurrentAry;
				SwapPoolData(nOutIndex,iIndexCurrentAry,nInIndex);
				m_MemPoolTable[nOutIndex].SetCurrentIndex(iIndexCurrentAry);
			}	

			return;
		}
	}

	//当找不到时说明不在内存池中直接释放
	//如果内存池关闭会清空动态数组内的所有元素,此时直接释放内存
	free(pBuffer);
	return ;
}

//交换处理,需交换内存快中的内部索引,同时也需要交换m_MemPoolTable中的位置
int CMemPool::SwapPoolData(int nOutIndex,int nIndex1,int nIndex2)
{
	if (nIndex2 == nIndex1)
	{
		return 0;
	}

	MemPoolData *_memData1  = (MemPoolData *)m_MemPoolTable[nOutIndex].GetNodeFromIndex(nIndex1);
	MemPoolData *_memData2  = (MemPoolData *)m_MemPoolTable[nOutIndex].GetNodeFromIndex(nIndex2);
	MemPoolData _memData    = *_memData1;
	*_memData1              = *_memData2;
	*_memData2              = _memData;
	m_MemPoolTable[nOutIndex].Swap(nIndex1,nIndex2);
	return 0;
}

/*******************************************************
重新整理内存池,检查空闲内存的闲置时间,超过MEMPOOL_TIMELIM毫秒就释放
同时也整理动态数组m_MemPoolTable避免占用太多无用内存
********************************************************/
void CMemPool::RebindMemPool()
{
	unsigned int nTime = time(0);
	for (int nOutIndex = 0;nOutIndex < MEMPOOL_MAX_COUNT;nOutIndex  )
	{
		CAutoLock lock(m_pMemPoolLock[nOutIndex]);
		int iIndexCurrentAry = m_MemPoolTable[nOutIndex].GetCurrentIndex();
		for (int nInIndex = 0;nInIndex <= iIndexCurrentAry;)
		{
			MemPoolData *pMemPoolData = (MemPoolData *)m_MemPoolTable[nOutIndex].GetNodeFromIndex(nInIndex);
			if (ch_FLASE == pMemPoolData->chbIsMemTrunkUsed && nTime - pMemPoolData->dwMemTrunkTicket > MEMPOOL_TIMELIM)
			{
				int iSizeNod = m_MemPoolTable[nOutIndex].GetSizeNode();
				m_MemPoolTable[nOutIndex].SetSizeNode(--iSizeNod);
				SwapPoolData(nOutIndex,nInIndex,iIndexCurrentAry);
				SwapPoolData(nOutIndex,iIndexCurrentAry,iSizeNod);
				m_MemPoolTable[nOutIndex].SetCurrentIndex(--iIndexCurrentAry);
				free(pMemPoolData);
				continue;
			}

			nInIndex  ;
		}

		m_MemPoolTable[nOutIndex].ReBindDyamicAry();
	}
}