码迷,mamicode.com
首页 > 编程语言 > 详细

内存池--伙伴算法的实践

时间:2015-01-17 01:03:07      阅读:374      评论:0      收藏:0      [点我收藏+]

标签:内存池   内存分配   内存   算法   源代码   

内存池主要分为三个部分:class buffer_t,class bufferpool_t,class mempool_t

1.class mempool_t:内存开辟与释放的接口,既可以通过内存池开辟释放或者在超过内存池最大内存分配大小时,通过系统进行开辟与释放。

2.class bufferpool_t:在mempool_t中申请的实际内存大小2^n(2^n<=最大内存分配大小)内存池)对应于一个bufferpool_t,一个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
		内存池将重系统分配内存,但是 释放的时候 也一定要调用
		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_-1)))
		{
			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 类型大小,一个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;
};
写的不好的地方,请指出

内存池--伙伴算法的实践

标签:内存池   内存分配   内存   算法   源代码   

原文地址:http://blog.csdn.net/hushujian/article/details/42622469

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!