内存池完整实现代码及一些思考
来源:互联网 发布:htc t328w软件下载 编辑:程序博客网 时间:2024/05/21 17:18
为了提高效率和有效的监控内存的实时状态,我们采取了内存池的思想来解决效率与对内存实现监控的问题。
网上查找到了一些方案,根据自己的理解实现了应用。
我们什么时候要调用到内存池,
1,当我们频繁的申请释放同样数据大小的内存空间,我们可以用比动态new更有效方式来管理内存时,我们应该用内存池来提高效率。
2,当我们需要知道内存实时的申请状态,以便于对于服务器内存状态做实时预警时,我们可以用内存池的接口,来给内存增加监控。
实现的特点:
1,内存池内存单元大小可以动态定义,实现多级内存池。
2,申请效率很高,单元测试下是普通new/delete的4倍左右,当然具体性能还应机器类别而异。
//作者冯宏华,徐莹,程远,汪磊享有论文著作权,由2011-06-06 konyel lin根据相关代码和理论进行优化修改。
#include <string>
#include <malloc.h>
//内存对齐值,可以根据机器取指长度进行设置
#define MEMPOOL_ALIGNMENT 4
#define USHORT unsigned short
#define ULONG unsigned long
struct MemoryBlock
{
USHORT nSize;
USHORT nFree;
USHORT nFirst;
USHORT nDummyAlign1;
MemoryBlock* pNext;
char aData[1];
static void* operator new(size_t,USHORT nTypes, USHORT nUnitSize){
return ::operator new(sizeof(MemoryBlock) + nTypes * nUnitSize);
}
static void operator delete(void *p, size_t){
::operator delete (p);
}
MemoryBlock (USHORT nTypes = 1, USHORT nUnitSize = 0);
~MemoryBlock() {}
};
class MemoryPool
{
private:
MemoryBlock* pBlock;
USHORT nUnitSize;
USHORT nInitSize;
USHORT nGrowSize;
public:
MemoryPool( USHORT nUnitSize,
USHORT nInitSize = 1024,
USHORT nGrowSize = 256 );
~MemoryPool();
void* Alloc();
void Free( void* p );
};
MemoryPool::MemoryPool( USHORT _nUnitSize,
USHORT _nInitSize, USHORT _nGrowSize )
{
pBlock = NULL;
nInitSize = _nInitSize;
nGrowSize = _nGrowSize;
if ( _nUnitSize > 4 )
nUnitSize = (_nUnitSize + (MEMPOOL_ALIGNMENT-1)) & ~(MEMPOOL_ALIGNMENT-1);
else if ( _nUnitSize <= 2 )
nUnitSize = 2;
else
nUnitSize = 4;
}
void* MemoryPool::Alloc()
{
MemoryBlock* pMyBlock;
if ( !pBlock ){
//第一次调用初始化内存块
pMyBlock =new(nGrowSize, nUnitSize) MemoryBlock(nGrowSize, nUnitSize);
pBlock = pMyBlock;
return (void*)(pMyBlock->aData);
}
pMyBlock = pBlock;
while (pMyBlock && !pMyBlock->nFree )
pMyBlock = pMyBlock->pNext;
if ( pMyBlock ){
printf("get a mem from block/n");
char* pFree = pMyBlock->aData+(pMyBlock->nFirst*nUnitSize);
//aData记录实际的内存单元标识
pMyBlock->nFirst = *((USHORT*)pFree);
pMyBlock->nFree--;
return (void*)pFree;
}
else{
printf("add a new block/n");
if (!nGrowSize)
return NULL;
pMyBlock = new(nGrowSize, nUnitSize) MemoryBlock(nGrowSize, nUnitSize);
if (!pMyBlock )
return NULL;
pMyBlock->pNext = pBlock;
pBlock = pMyBlock;
return (void*)(pMyBlock->aData);
}
}
void MemoryPool::Free( void* pFree ){
MemoryBlock* pMyBlock = pBlock;
MemoryBlock* preMyBlock;
//确定该待回收分配单元(pFree)落在哪一个内存块的指针范围内,大于起始节点,小于终止节点。
while ( ((ULONG)pMyBlock->aData > (ULONG)pFree) ||
((ULONG)pFree >= ((ULONG)pMyBlock->aData + pMyBlock->nSize))){
//不在内存块范围内,则历遍下一个节点
preMyBlock=pMyBlock;
pMyBlock=pMyBlock->pNext;
}
pMyBlock->nFree++;
*((USHORT*)pFree) = pMyBlock->nFirst;
pMyBlock->nFirst = (USHORT)(((ULONG)pFree-(ULONG)(pBlock->aData)) / nUnitSize);
//判断内存块是否全部为自由状态,是则释放整个内存块
if (pMyBlock->nFree*nUnitSize == pMyBlock->nSize ){
preMyBlock->pNext=pMyBlock->pNext;
delete pMyBlock;
}
}
MemoryBlock::MemoryBlock (USHORT nTypes, USHORT nUnitSize)
: nSize (nTypes * nUnitSize),
nFree (nTypes - 1),
nFirst (1),
pNext (0)
{
char * pData = aData;
for (USHORT i = 1; i < nTypes; i++) {
//将内存块的前2个字节用来存放内存单元的标识
*reinterpret_cast<USHORT*>(pData) = i;
pData += nUnitSize;
}
}
- 内存池完整实现代码及一些思考
- 内存池完整实现代码及一些思考
- 黑马程序员——多线程代码实践及一些思考
- 代码的一些思考
- 鼠标拖拽效果原理及完整代码实现
- 手工实现字节对齐 及 代码质量思考
- 手工实现字节对齐 及 代码质量思考
- 关于代码的一些思考
- poj3258 二分及一些思考
- word2vector 一些问题及思考
- SVM一些问题及思考
- C语言实现大整数乘法代码的完整代码及运行结果
- 关于Java内存溢出的一些思考
- 彩色图像直方图均衡化及颜色直方图显示 opencv实现 完整代码及详细注释
- 彩色图像直方图均衡化及颜色直方图显示 opencv实现 完整代码及详细注释
- 一些字符串及内存操作的函数的实现
- 一些字符串及内存操作函数的实现
- 编程珠玑学习笔记 Aha算法 思考以及一些代码实现
- SQL Server 2000索引重构方法
- Javascript数组函数及用法示例
- 网站页面加载性能测试工具
- 成员初始化列表的概要介绍
- joj2075
- 内存池完整实现代码及一些思考
- C语言中的一些事
- windows hook 之IAT篇
- DetailsView控件的使用:http://technet.microsoft.com/zh-cn/7z482d0y
- 用开放平台账号登录第三方网站
- Android 的科普知识
- MFC 让对话框不显示在任务栏和桌面
- bios开发工具推荐 google desktop
- JCO 2.1.7 下载