一个高效的内存池实现
来源:互联网 发布:新闻类数据库设计 编辑:程序博客网 时间:2024/06/06 20:14
在高效C++编程中看到一个不错的内存池实现方案,这里共享下,大家看看有什么不足。
代码很简单,如下:
它的实现思想就是每次从List的头上取内存, 如果取不到则重新分配一定数量; 用完后把内存放回List头部,这样的话效率很高,因为每次List上可以取到的话,肯定是空闲的内存。
当然上面的代码只是针对单线程的,要支持多线程的话也很简单,外面加一层就可以了,
代码如下:
这是我的测试代码:
代码很简单,如下:
template<typename T>
class CMemoryPool
{
public:
enum { EXPANSION_SIZE = 32};
CMemoryPool(unsigned int nItemCount = EXPANSION_SIZE)
{
ExpandFreeList(nItemCount);
}
~CMemoryPool()
{
//free all memory in the list
CMemoryPool<T>* pNext = NULL;
for(pNext = m_pFreeList; pNext != NULL; pNext = m_pFreeList)
{
m_pFreeList = m_pFreeList->m_pFreeList;
delete [](char*)pNext;
}
}
void* Alloc(unsigned int /*size*/)
{
if(m_pFreeList == NULL)
{
ExpandFreeList();
}
//get free memory from head
CMemoryPool<T>* pHead = m_pFreeList;
m_pFreeList = m_pFreeList->m_pFreeList;
return pHead;
}
void Free(void* p)
{
//push the free memory back to list
CMemoryPool<T>* pHead = static_cast<CMemoryPool<T>*>(p);
pHead->m_pFreeList = m_pFreeList;
m_pFreeList = pHead;
}
protected:
//allocate memory and push to the list
void ExpandFreeList(unsigned nItemCount = EXPANSION_SIZE)
{
unsigned int nSize = sizeof(T) > sizeof(CMemoryPool<T>*) ? sizeof(T) : sizeof(CMemoryPool<T>*);
CMemoryPool<T>* pLastItem = static_cast<CMemoryPool<T>*>(static_cast<void*>(new char[nSize]));
m_pFreeList = pLastItem;
for(int i=0; i<nItemCount-1; ++i)
{
pLastItem->m_pFreeList = static_cast<CMemoryPool<T>*>(static_cast<void*>(new char[nSize]));
pLastItem = pLastItem->m_pFreeList;
}
pLastItem->m_pFreeList = NULL;
}
private:
CMemoryPool<T>* m_pFreeList;
};
class CMemoryPool
{
public:
enum { EXPANSION_SIZE = 32};
CMemoryPool(unsigned int nItemCount = EXPANSION_SIZE)
{
ExpandFreeList(nItemCount);
}
~CMemoryPool()
{
//free all memory in the list
CMemoryPool<T>* pNext = NULL;
for(pNext = m_pFreeList; pNext != NULL; pNext = m_pFreeList)
{
m_pFreeList = m_pFreeList->m_pFreeList;
delete [](char*)pNext;
}
}
void* Alloc(unsigned int /*size*/)
{
if(m_pFreeList == NULL)
{
ExpandFreeList();
}
//get free memory from head
CMemoryPool<T>* pHead = m_pFreeList;
m_pFreeList = m_pFreeList->m_pFreeList;
return pHead;
}
void Free(void* p)
{
//push the free memory back to list
CMemoryPool<T>* pHead = static_cast<CMemoryPool<T>*>(p);
pHead->m_pFreeList = m_pFreeList;
m_pFreeList = pHead;
}
protected:
//allocate memory and push to the list
void ExpandFreeList(unsigned nItemCount = EXPANSION_SIZE)
{
unsigned int nSize = sizeof(T) > sizeof(CMemoryPool<T>*) ? sizeof(T) : sizeof(CMemoryPool<T>*);
CMemoryPool<T>* pLastItem = static_cast<CMemoryPool<T>*>(static_cast<void*>(new char[nSize]));
m_pFreeList = pLastItem;
for(int i=0; i<nItemCount-1; ++i)
{
pLastItem->m_pFreeList = static_cast<CMemoryPool<T>*>(static_cast<void*>(new char[nSize]));
pLastItem = pLastItem->m_pFreeList;
}
pLastItem->m_pFreeList = NULL;
}
private:
CMemoryPool<T>* m_pFreeList;
};
它的实现思想就是每次从List的头上取内存, 如果取不到则重新分配一定数量; 用完后把内存放回List头部,这样的话效率很高,因为每次List上可以取到的话,肯定是空闲的内存。
当然上面的代码只是针对单线程的,要支持多线程的话也很简单,外面加一层就可以了,
代码如下:
class CCriticalSection
{
public:
CCriticalSection()
{
InitializeCriticalSection(&m_cs);
}
~CCriticalSection()
{
DeleteCriticalSection(&m_cs);
}
void Lock()
{
EnterCriticalSection(&m_cs);
}
void Unlock()
{
LeaveCriticalSection(&m_cs);
}
protected:
CRITICAL_SECTION m_cs;
};
template<typename POOLTYPE, typename LOCKTYPE>
class CMTMemoryPool
{
public:
void* Alloc(unsigned int size)
{
void* p = NULL;
m_lock.Lock();
p = m_pool.Alloc(size);
m_lock.Unlock();
return p;
}
void Free(void* p)
{
m_lock.Lock();
m_pool.Free(p);
m_lock.Unlock();
}
private:
POOLTYPE m_pool;
LOCKTYPE m_lock;
};
{
public:
CCriticalSection()
{
InitializeCriticalSection(&m_cs);
}
~CCriticalSection()
{
DeleteCriticalSection(&m_cs);
}
void Lock()
{
EnterCriticalSection(&m_cs);
}
void Unlock()
{
LeaveCriticalSection(&m_cs);
}
protected:
CRITICAL_SECTION m_cs;
};
template<typename POOLTYPE, typename LOCKTYPE>
class CMTMemoryPool
{
public:
void* Alloc(unsigned int size)
{
void* p = NULL;
m_lock.Lock();
p = m_pool.Alloc(size);
m_lock.Unlock();
return p;
}
void Free(void* p)
{
m_lock.Lock();
m_pool.Free(p);
m_lock.Unlock();
}
private:
POOLTYPE m_pool;
LOCKTYPE m_lock;
};
这是我的测试代码:
#include <iostream>
#include <windows.h>
using namespace std;
#include "MemoryPool.h"
#include "MTMemoryPool.h"
class CTest
{
public:
int m_n;
int m_n1;
void* operator new(size_t size)
{
void* p = s_pool->Alloc(size);
return p;
}
void operator delete(void* p, size_t size)
{
s_pool->Free(p);
}
static void NewPool()
{
//s_pool = new CMemoryPool<CTest>;
s_pool = new CMTMemoryPool<CMemoryPool<CTest>, CCriticalSection>;
}
static void DeletePool()
{
delete s_pool;
s_pool = NULL;
}
//static CMemoryPool<CTest>* s_pool;
static CMTMemoryPool<CMemoryPool<CTest>, CCriticalSection>* s_pool;
};
//CMemoryPool<CTest>* CTest::s_pool = NULL;
CMTMemoryPool<CMemoryPool<CTest>, CCriticalSection>* CTest::s_pool = NULL;
void testFun()
{
int i;
const int nLoop = 10;
const int nCount = 10000;
for(int j = 0; j<nLoop; ++j)
{
typedef CTest* LPTest;
LPTest arData[nCount];
for(i=0;i <nCount; ++i)
{
arData[i] = new CTest;
}
for(i=0;i <nCount; ++i)
{
delete arData[i];
}
}
}
int main(int argc, char* argv[])
{
{
unsigned int dwStartTickCount = GetTickCount();
CTest::NewPool();
testFun();
CTest::DeletePool();
cout << "total cost" << GetTickCount() - dwStartTickCount << endl;
}
system("pause");
return 0;
}
#include <windows.h>
using namespace std;
#include "MemoryPool.h"
#include "MTMemoryPool.h"
class CTest
{
public:
int m_n;
int m_n1;
void* operator new(size_t size)
{
void* p = s_pool->Alloc(size);
return p;
}
void operator delete(void* p, size_t size)
{
s_pool->Free(p);
}
static void NewPool()
{
//s_pool = new CMemoryPool<CTest>;
s_pool = new CMTMemoryPool<CMemoryPool<CTest>, CCriticalSection>;
}
static void DeletePool()
{
delete s_pool;
s_pool = NULL;
}
//static CMemoryPool<CTest>* s_pool;
static CMTMemoryPool<CMemoryPool<CTest>, CCriticalSection>* s_pool;
};
//CMemoryPool<CTest>* CTest::s_pool = NULL;
CMTMemoryPool<CMemoryPool<CTest>, CCriticalSection>* CTest::s_pool = NULL;
void testFun()
{
int i;
const int nLoop = 10;
const int nCount = 10000;
for(int j = 0; j<nLoop; ++j)
{
typedef CTest* LPTest;
LPTest arData[nCount];
for(i=0;i <nCount; ++i)
{
arData[i] = new CTest;
}
for(i=0;i <nCount; ++i)
{
delete arData[i];
}
}
}
int main(int argc, char* argv[])
{
{
unsigned int dwStartTickCount = GetTickCount();
CTest::NewPool();
testFun();
CTest::DeletePool();
cout << "total cost" << GetTickCount() - dwStartTickCount << endl;
}
system("pause");
return 0;
}
在我机器上测试结果比系统默认的CRT实现高效N倍。
转载:http://www.cppblog.com/weiym/archive/2012/05/05/173785.html
- 一个高效的内存池实现
- 一个高效的内存池实现
- 一个高效的内存池实现
- 一个高效的内存池实现
- 一个高效的内存池实现
- 一个高效的内存池实现
- C++中一个高效的内存池实现
- 一个高效的内存池算法
- 内存池--高效实现
- 固定的,高效的内存池实现机器应用
- 基于策略的一种高效内存池的实现
- 基于策略的一种高效内存池的实现
- 各种池---内存池的高效实现(C语言)
- MemoryPool —— 简单高效的内存池 allocator 实现
- 自己实现的一个高效快速排序: )
- 编程:实现一个高效的缓存系统?
- 如何实现一个高效的队列
- 一个简单的内存池的实现
- 基于网页的mini2440视频监控
- poj 1952 BUY LOW, BUY LOWER(求最长下降子序列个数)
- Windows系统下设置erlang起始目录
- 芯片风波
- iPhone / iPod Touch 文件传输解决方案 – Cocoa Web Resource Project
- 一个高效的内存池实现
- SPRING两本书
- MyEclipse8.0集成JBPM3.2.3
- hdu 4524 郑厂长系列故事——逃离迷宫 小水题
- Python 私有函数
- [Core Java. Volume I. Fundamentals, 8th Edition]-7,8
- google blink的设计计划: Out-of-Progress iframes
- 改变UITabBarController的高度方法
- c++中c_str() 和 strtok 的用法