实例介绍
【实例简介】
【实例截图】
【实例截图】
【核心代码】
//#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();
}
}
好例子网口号:伸出你的我的手 — 分享!
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论