内存池--伙伴算法的实践
来源:程序员人生 发布时间:2015-02-06 08:58:01 阅读次数:3976次
内存池主要分为3个部份:class buffer_t,class bufferpool_t,class mempool_t
1.class mempool_t:内存开辟与释放的接口,既可以通过内存池开辟释放或在超过内存池最大内存分配大小时,通过系统进行开辟与释放。
2.class bufferpool_t:在mempool_t中申请的实际内存大小2^n(2^n<=最大内存分配大小)内存池)对应于1个bufferpool_t,1个bufferpool_t由list链表来管理多个2^n大小的内存块
3.class buffer_t:对实际内存块进行管理与存储。
话不多说,直接上源代码。
class mempool_t:
#include "bufferpool_t.h"
class mempool_t
{
public:
static mempool_t *get_instance();
/*
申请内存
@param uint32_t size_ 内存大小
如果size_ 大与max_alloc_size 将重系统要求内存
*/
void *alloc(uint32_t size_);
/*
释放内存
@param void* 内存句柄
*/
bool free(void* ptr);
/*
配置内存池最大内存分配大小
@param uint32_t max_alloc_size.
如果 mempool_t.alloc (size):其中 size > max_alloc_size
内存池将重系统分配内存,但是 释放的时候 也1定要调用
mempool_t.free 来释放,否则会内存毛病
*/
void config(const uint32_t &max_alloc_size = 1<<20);
private:
mempool_t(void);
~mempool_t(void);
typedef std::map<uint32_t ,bufferpool_t *> bufferpool_set_t;
bool get_bufferpool_size( uint32_t size_, uint32_t &buf_size_ );
/*向系统要求分配内存
@param uint32_t size_ 内存大小
@return void* 内存句柄
*/
void * internal_malloc( const uint32_t &size_ );
/*直接释放内存
@param void *ptr_ 内存句柄
@return bool true成功, false失败,缘由是内存不是internal_malloc返回的,
或是内存已被破坏了*/
bool internal_free(void *ptr_);
bufferpool_set_t bufferpool_set;
uint32_t max_alloc_size;
std::mutex bufferpool_set_mutex;
};
#include "stdafx.h"
#include "mempool_t.h"
mempool_t::mempool_t(void)
:max_alloc_size(1<<20)//1MB
{
}
mempool_t::~mempool_t(void)
{
while (bufferpool_set.empty()==false)
{
bufferpool_t *bufferpool = bufferpool_set.begin()->second;
bufferpool_set.erase(bufferpool_set.begin());
delete bufferpool;
}
}
//设置内存分配对象的实例
mempool_t * mempool_t::get_instance()
{
static mempool_t *instance = new mempool_t;
return instance;
}
void * mempool_t::alloc( uint32_t size_ )
{
uint32_t buf_size;
void *buf;
bool rc = get_bufferpool_size(size_,buf_size);
if (rc)
{
bufferpool_t *bufferpool;
std::lock_guard<std::mutex> lock_guard(bufferpool_set_mutex);
bufferpool_set_t::iterator it = bufferpool_set.find(buf_size);
if (it == bufferpool_set.end ())
{
bufferpool = new bufferpool_t(buf_size);
bool rc = bufferpool_set.insert (
bufferpool_set_t::value_type(buf_size,bufferpool)).second;
assert(rc);
}
else
{
bufferpool = it->second;
}
buf =(void*) bufferpool->alloc_buffer ();
}
else
{
buf = internal_malloc(size_);
}
return buf;
}
bool mempool_t::free( void* ptr )
{
uint32_t data_size;
bool rc = bufferpool_t::get_buffer_size ((char*)ptr,data_size);
if (rc)
{
std::lock_guard<std::mutex> lock_guard(bufferpool_set_mutex);
bufferpool_t *bufferpool;
bufferpool_set_t::iterator it = bufferpool_set.find(data_size);
if (it == bufferpool_set.end ())
{
assert(false);
}
bufferpool = it->second;
return bufferpool->free_buffer ((char*)ptr);;
}
else
{
return internal_free (ptr);
}
return false;
}
bool mempool_t::internal_free( void* ptr_)
{
char *buf = (char*)ptr_ - sizeof(uint32_t);
uint32_t size = *(uint32_t*)buf;
if (size > max_alloc_size)
{
uint32_t tail_size = *(uint32_t*)((char*)ptr_ + size);
if (tail_size == size)
{
delete buf;
return true;
}
}
return false;
}
bool mempool_t::get_bufferpool_size( uint32_t size_, uint32_t &buf_size_ )
{
if (size_ > max_alloc_size) {
return false;
}
/*
求整数的最接近2的幂,
向上对齐
*/
size_ = size_ - 1;
size_ = size_ | (size_ >> 1);
size_ = size_ | (size_ >> 2);
size_ = size_ | (size_ >> 4);
size_ = size_ | (size_ >> 8);
size_ = size_ | (size_ >>16);
size_ = size_ + 1;
/*判断是不是是2的幂*/
if(0 != (size_&(size_⑴)))
{
assert(false);
}
buf_size_ = size_;
return true;
}
void * mempool_t::internal_malloc( const uint32_t &size_ )
{
uint32_t buf_size = size_ + sizeof(uint32_t)*2;
void *buf = malloc (buf_size);
*(uint32_t*)buf = size_;
*(uint32_t*)((char*)buf + sizeof(uint32_t)+size_) = size_;
return ((char*)buf+sizeof(uint32_t));
}
void mempool_t::config( const uint32_t &max_buffer_size_ )
{
max_alloc_size = max_buffer_size_;
}
class
bufferpool_t:
#include "buffer_t.hpp"
class bufferpool_t
{
public:
bufferpool_t(const uint32_t &buffer_size_,const uint32_t &limit_size_ = 20);
~bufferpool_t(void);
char *alloc_buffer();
bool free_buffer(char *buffer_);
static bool get_buffer_size(char *buffer_, uint32_t &buffer_size_);
private:
typedef std::list<buffer_t*> buffer_list_t;
buffer_list_t buffer_list;
//buffer 类型大小,1个bufferpool_t只管理
//一样大小的内存
uint32_t buffer_type_size;
//空闲内存最大数量
uint32_t limit_buffer_list_size;
//获得内存次数
uint32_t alloc_times;
//释放内存次数
uint32_t free_times;
};
#include "stdafx.h"
#include "bufferpool_t.h"
bufferpool_t::bufferpool_t(const uint32_t &buffer_size_,const uint32_t &limit_size_)
{
buffer_type_size = buffer_size_;
limit_buffer_list_size = limit_size_;
free_times = 0;
alloc_times = 0;
}
bufferpool_t::~bufferpool_t(void)
{
buffer_t *buffer;
while (buffer_list.empty () == false)
{
buffer = buffer_list.front ();
buffer_list.pop_back ();
buffer->relase_buffer();
}
}
char * bufferpool_t::alloc_buffer()
{
buffer_t *buffer;
char *buf;
if (buffer_list.empty ())
{
char *buf = new char[buffer_type_size+sizeof(buffer_t)];
buffer = new (buf)buffer_t(buffer_type_size,buf);
//添加成员
}
else
{
buffer = buffer_list.front ();
buffer_list.pop_front ();
}
++alloc_times ;
buf = buffer->buf ();
buffer->use (true);
return buf;
}
bool bufferpool_t::free_buffer( char * buffer_)
{
buffer_t *buffer = (buffer_t*)(buffer_ - sizeof(buffer_t));
if (buffer->check_code () && buffer->length () == buffer_type_size)
{
if(buffer_list.size () < limit_buffer_list_size)
{
buffer->use (false);
buffer_list.push_back (buffer);
++free_times;
return true;
}
else
{
buffer->relase_buffer();
return true;
}
}
return false;
}
bool bufferpool_t::get_buffer_size( char *buffer_ ,uint32_t &buffer_size_)
{
buffer_t *buffer = (buffer_t*)(buffer_ - sizeof(buffer_t));
if (buffer->check_code () &&
buffer->use()&&
buffer->buf () == buffer_)
{
buffer_size_ = buffer->length ();
return true;
}
else
{
return false;
}
}
class buffer_t:
#pragma once
#include "stddef.hpp"
class buffer_t
{
public:
inline buffer_t(uint32_t length_, char *data_buf_)
{
buf_code = 0xbeaf;
buf_length = length_;
buf_data = data_buf_;
}
inline void relase_buffer(void)
{
delete []buf_data;
}
inline bool check_code()
{
return buf_code == 0xbeaf;
}
inline char *buf()
{
return buf_data+sizeof(*this);
}
inline uint32_t length()
{
return buf_length;
}
inline bool use()
{
return is_use;
}
inline void use(const bool &is_use_)
{
is_use = is_use_;
}
private:
char *buf_data;
bool is_use;
uint32_t buf_code;
uint32_t buf_length;
};
写的不好的地方,请指出
生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠