概述
问题描述:
1.众所周知,内存管理机制几乎存在于一切优秀的系统中。这样做原因不外乎以下几点:1.改善性能;2.减少碎片的产生;3.侦测系统的内存使用情况,便于调错,便于了解系统的内存使用,以对系统的架构从内存使用层面上进行设计考量;
2.我前面有文已经说明,内存管理的机制一般分为:1.预先分配大量等尺寸的块,自己维护,逐次满足对单个内存单元的请求;2.释放的内存也自己维护,以便重复使用;3.使用定长和变长机制进行内存管理。
3.本文试着以较大尺寸(4096)的内存块为分配单元,然后在一个块中利用指针偏移来满足小对象的内存申请,当当前块内存耗尽时,又分配同样尺寸的内存块,重复以前工作。块与块之间靠指针维护(next)。
4.程序交还的内存,以内存尺寸为键,存入STL map;
5.当STL map中有内存时,优先从此中寻找满足的给定尺寸的内存需求;
6.和直接系统申请内存对比测试,发现,执行相同的操作,本内存管理器所消耗时间仅为系统内存申请耗时的十分之一;
程序代码:
#ifndef _MEMORY_BLOCK_POOL_H_
#define _MEMORY_BLOCK_POOL_H_
#include <stdlib.h>
#include <vector>
#include "windows.h"
#define ALIGN( size, bits ) ( ( ( ( size - 1 ) >> bits ) + 1 ) << bits )
/*
* memory pool fixed length block
*
*
*/
class MemoryBlockPool
{
public:
static const int MAXBLOCK = 256;
static const int MALLOCKSIZE = 4096;
static const int DEFAULTBASELEN = 4;
typedef struct tagMemStatInfo
{
char* allocMem;
size_t allocSize;
tagMemStatInfo():allocMem(0),allocSize(0)
{
}
tagMemStatInfo( char* mem, size_t size ):allocMem(mem),
allocSize(size)
{
}
}MemStatInfo, *pMemStatInfo;
typedef struct tagMemoryBlock
{
std::vector<char*> Block;
size_t validIdx;
tagMemoryBlock():Block(), validIdx(0)
{
}
}MemoryBlock, *pMemoryBlock;
typedef std::vector<char*> BlockContainer;
/*
*
*
*/
MemoryBlockPool( size_t baseLen = DEFAULTBASELEN ):m_pool(0),
m_poolSize(0), m_baseLen(baseLen),
m_memStat()
{
Init( m_baseLen );
}
/*
*
*
*/
~MemoryBlockPool()
{
Release();
}
/*
* Release all memory allocated
*
*/
void Release()
{
std::vector<MemStatInfo>::iterator iter = m_memStat.begin();
while( iter != m_memStat.end() )
{
free( iter->allocMem );
++iter;
}
for( size_t i = 0; i < m_poolSize; i++ )
{
m_pool[i].Block.clear();
}
}
/*
* get memory for given length from cahce array or os
*
*/
void* Malloc( size_t len )
{
assert( len > 0 );
size_t size = ALIGN( len, 2 );
if( size > MAXBLOCK )
{
return malloc(size);
}
if( !m_pool[size].Block.size() )
{
size_t memLen = size + 4;
char* buf = (char*)malloc( MALLOCKSIZE );
size_t blockNums = MALLOCKSIZE / memLen;
BlockContainer& container = m_pool[size].Block;
container.reserve( blockNums );
for( size_t i = 0; i < blockNums; i++ )
{
*(buf + i * size) = i;
container.push_back( buf + i * size );
}
m_memStat.push_back( MemStatInfo( buf, MALLOCKSIZE ) );
}
else if( m_pool[size].validIdx == m_pool[size].Block.size() )
{
size_t memLen = size + 4;
char* buf = (char*)malloc( MALLOCKSIZE );
size_t blockNums = MALLOCKSIZE / memLen;
BlockContainer& container = m_pool[size].Block;
for( size_t i = 0; i < blockNums; i++ )
{
*(int*)(buf + i * size) = i + container.size();
container.push_back( buf + i * size );
}
}
char* buf = m_pool[size].Block.at( m_pool[size].validIdx );
m_pool[size].validIdx++;
return buf + 4;
}
/*
* give back memory to cache or os
*
*/
void Free( void* mem, size_t len )
{
assert( len > 0 );
size_t size = ALIGN( len, 2 );
if( size > MAXBLOCK )
{
return free( mem );
}
char* buf = (char*)mem;
buf -= 4;
if( m_pool[size].validIdx )
{
Swap( m_pool[size].Block.at( m_pool[size].validIdx - 1), buf );
m_pool[size].validIdx--;
}
}
private:
void Swap( char*& bufFirst, char*& bufSecond )
{
char* temp = bufFirst;
bufFirst = bufSecond;
bufSecond = temp;
}
/*
*
*
*/
void Init( size_t baseLen )
{
m_poolSize = MAXBLOCK / baseLen;
m_pool = new MemoryBlock[m_poolSize];
}
private:
MemoryBlock *m_pool; // memory block array
size_t m_poolSize; // the size of memory block array
size_t m_baseLen; //
std::vector<MemStatInfo> m_memStat;
};
//test object one
typedef struct tagTestObjFirst
{
int first;
int second;
tagTestObjFirst():first(0), second(0)
{
}
tagTestObjFirst( int i, int j ):first(i), second(j)
{
}
}TestObjFirst, *pTestObjFrist;
// test object two
typedef struct tagTestObjSecond
{
int first;
int second;
std::string name;
tagTestObjSecond():first(0), second(0)
{
}
tagTestObjSecond( int i, int j, const char* str ):first(i), second(j), name( str )
{
}
}TestObjSecond, *pTestObjSecond;
/*
* Test os memory operation
*
*/
void BlockTestOSMemory()
{
unsigned long start = GetTickCount();
const int len = 2000000;
int halfLen = len / 2;
pTestObjFrist* objs = new pTestObjFrist[len];
pTestObjSecond* objExts = new pTestObjSecond[len];
for( int i = 0; i < len; i++ )
{
objs[i] = new TestObjFirst( i, i );
objExts[i] = new TestObjSecond( i, i, "test" );
delete objs[i];
delete objExts[i];
}
unsigned long interval = GetTickCount() - start;
printf(" system call consume time %d for memory operation n", interval );
delete [] objs;
delete [] objExts;
}
/*
*Test memory pool
*
*
*/
void BlockTestMemoryBlock()
{
unsigned long start = GetTickCount();
const int len = 2000000;
int halfLen = len / 2;
MemoryBlockPool memPool;
pTestObjFrist* objs = new pTestObjFrist[len];
pTestObjSecond* objExts = new pTestObjSecond[len];
for( int i = 0; i < len; i++ )
{
void* buf = memPool.Malloc( sizeof(TestObjFirst) );
objs[i] = new (buf) TestObjFirst( i, i );
buf = memPool.Malloc( sizeof(TestObjSecond) );
objExts[i] = new (buf) TestObjSecond( i, i, "test" );
memPool.Free( buf, sizeof(TestObjFirst) );
memPool.Free( buf, sizeof(TestObjSecond) );
}
unsigned long interval = GetTickCount() - start;
printf(" memory pool call consume time %d for memory operation n", interval );
delete [] objs;
delete [] objExts;
}
/*
*Test interface for memory operation
*
*
*/
void TestSuiteCacheBlock()
{
BlockTestMemoryBlock();
BlockTestOSMemory();
}
#endif
compile and run in visual studio 2005
最后
以上就是香蕉寒风为你收集整理的一个利用memory block分配机制的高性能的内存管理器类的全部内容,希望文章能够帮你解决一个利用memory block分配机制的高性能的内存管理器类所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复