內存池--伙伴算法的實踐
來源:程序員人生 發布時間:2015-02-06 08:58:01 閱讀次數:4175次
內存池主要分為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;
};
寫的不好的地方,請指出
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈