一个分配固定大小块的内存池(memory pool) 的例子 FROM POCO

//
// MemoryPool.h
//
// $Id: //poco/1.4/Foundation/include/Poco/MemoryPool.h#1 $
//
// Library: Foundation
// Package: Core
// Module:MemoryPool
//
// Definition of the MemoryPool class.
//
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//

/*
//z 2011-06-23 15:13:[email protected] 转载请注明出处
设计思想:
比较简单,申请若干个(128)固定大小的内存块,
将各内存块指针存放在vector中,申请则出vector,释放则回收到vec中去。
*/

#ifndef Foundation_MemoryPool_INCLUDED
#define Foundation_MemoryPool_INCLUDED


#include "Poco/Foundation.h"
#include "Poco/Mutex.h"
#include <vector>
#include <cstddef>


namespace Poco {

/*
14:01 2011-6-23
一个固定大小内存块的pool
这个class的主要目的是加速内存分配
同时在相同大小的块一遍又一遍分配时避免了内存碎片
*/

class Foundation_API MemoryPool
/// A simple pool for fixed-size memory blocks.
///
/// The main purpose of this class is to speed-up
/// memory allocations, as well as to reduce memory
/// fragmentation in situations where the same blocks
/// are allocated all over again, such as in server
/// applications.
///
/// All allocated blocks are retained for future use.
/// A limit on the number of blocks can be specified.
/// Blocks can be preallocated.
{
public :
MemoryPool(std::size_t blockSize,int preAlloc =0 ,int maxAlloc =0 );
//z@is2120 14:03 2011-6-23
//z 使用给定的blocksize创建一个memorypool。
//z 预分配的大小由preAlloc指定
/// Creates a MemoryPool for blocks with the given blockSize.
/// The number of blocks given in preAlloc are preallocated.

~MemoryPool();

//z 从memory pool中得到一个block
void * get();
/// Returns a memory block. If there are no more blocks
/// in the pool, a new block will be allocated.
///
/// If maxAlloc blocks are already allocated, an
/// OutOfMemoryException is thrown.

//z 将一个 memory block 返回到pool中去。
void release(void * ptr);
/// Releases a memory block and returns it to the pool.

//z 返回 block size
std::size_t blockSize()const ;
/// Returns the block size.

//z 返回已分配的 blocks 的数目
int allocated()const ;
/// Returns the number of allocated blocks.

//z 返回在pool中可用的块数目
int available()const ;
/// Returns the number of available blocks in the pool.

private :
//z 禁用了默认构造函数;拷贝构造函数以及赋值构造函数
MemoryPool();
MemoryPool(const MemoryPool&);
MemoryPool&operator = (const MemoryPool&);

//z 保留128的block
enum
{
BLOCK_RESERVE =128
};

//z 使用了vector来保存block的地址
typedef std::vector<char *> BlockVec;

//z 块大小
std::size_t _blockSize;
//z 允许的最大块数目
int _maxAlloc;
//z 已分配
int _allocated;
//z 存储块地址的容器
BlockVec_blocks;
//z 互斥
FastMutex _mutex;
};


//
// inlines
//
//z 返回块大小
inline std::size_t MemoryPool::blockSize()const
{
return _blockSize;
}

//z 返回总的分配的数目
inline int MemoryPool::allocated()const
{
return _allocated;
}

//z 凡存在blocks中的都是未交付使用的(但已分配)
inline int MemoryPool::available()const
{
return (int ) _blocks.size();
}


}// namespace Poco


#endif // Foundation_MemoryPool_INCLUDED

#include "Poco/MemoryPool.h"
#include "Poco/Exception.h"

namespace Poco {


MemoryPool::MemoryPool(std::size_t blockSize,int preAlloc,int maxAlloc):
_blockSize(blockSize),
_maxAlloc(maxAlloc),
_allocated(preAlloc)
{
poco_assert (maxAlloc ==0 || maxAlloc >= preAlloc);
poco_assert (preAlloc >=0 && maxAlloc >=0 );

int r = BLOCK_RESERVE;
if (preAlloc > r)
r = preAlloc;
if (maxAlloc >0 && maxAlloc < r)
r = maxAlloc;

//z vector 保留r空间
_blocks.reserve(r);

for (int i =0 ; i < preAlloc; ++i)
{
//z 直接分配;此时会不会出现异常?
_blocks.push_back(new char [_blockSize]);
}
}

MemoryPool::~MemoryPool()
{
//z 所有的都放在blockvec中
for (BlockVec::iterator it = _blocks.begin(); it != _blocks.end(); ++it)
{
delete [] *it;
}
}


void * MemoryPool::get()
{
FastMutex::ScopedLock lock(_mutex);

if (_blocks.empty())
{
if (_maxAlloc ==0 || _allocated < _maxAlloc)
{
++_allocated;
return new char [_blockSize];
}
else throw OutOfMemoryException("MemoryPool exhausted" );
}
else
{
//z 从尾端取出一个
char * ptr = _blocks.back();
//z 从尾端弹出
_blocks.pop_back();
return ptr;
}
}


void MemoryPool::release(void * ptr)
{
FastMutex::ScopedLock lock(_mutex);

//z 将get的内存还回vec中去。
_blocks.push_back(reinterpret_cast <char *>(ptr));
}


}// namespace Poco

你可能感兴趣的:(memory)