STL空间配置器

本文介绍了STL空间配置器的工作原理,包括第一级和第二级配置器的作用机制。第一级配置器处理大块内存分配,而第二级配置器则通过自由链表和内存池来提高小对象内存分配的效率,解决了内存碎片问题,并提升了内存分配速度。

STL空间配置器分为第一级配置器与第二级配置器,主要用来对内存的申请与释放。

第一级配置器:调用的是malloc/free,并有 new-handle 机制

第二级配置器:由自由链表及内存池组成

                           自由链表一个存储16个空闲块列表表头的数组free_list;

                      内存池起始地址的指针start_free和一个指向结束地址的指针end_free之间的内存

程序中的小对象的分配极易造成内存碎片(也叫外碎片),给操作系统的内存管理带来了很大压力,系统中碎片的增多不但会影响内存分配的速度,而且会极大地降低内存的利用率。

使用空间配置器,提高了空间的利用率和内存的分配速度,主要原因是:

(1)当内存申请超过128字节时,就会被视为大块内存,由第一级空间配置器处理;

(2)当内存申请小于等于128字节时,会对其使用二级空间配置

       a) 先查找自由链表,如有空间,直接分配即可;

       b)当a)不满足时,便会向内存池申请大块内存,一块返回申请,另外的挂到自由链表上,当反复申请该大小内存时,便极大的 提高了分配速度;

       c)当内存池内存不足时,只返回满足要求的申请即可,适量分配空间;

       d) 当内存池也满足不了要求时,便会向系统 malloc 一大段空间给内存池,再继续满足申请

       e) 当系统内存紧张时,便会返回到看自由链表是否有闲置空间可释放至内存池;

       f)  到山穷水尽的地步,便移交第一级空间配置器处理

优点:(1)小对象的内存申请与释放快速(不用每次都要操作系统完成);

        (2)解决了内存碎片的问题(外碎片);

        (3)提高了空间利用率

缺点:引入了内碎片的问题

//第一级空间配置
template<int inst>
class __MallocAllocTemplate
{
public:
	static void *Oom_Malloc(size_t size)
	{
		void(*my_malloc_handler)();
		void *result;

		while (1)
		{
			my_malloc_handler = __Malloc_Alloc_Oom_Handler;
			if (my_malloc_handler == NULL)
			{
				throw bad_alloc();
			}
			(*my_malloc_handler)();
			result = malloc(size);
			if (result) 
				return(result);
		}
	}
	static void * Allocate(size_t n)
	{
		void *result = malloc(n);
		if (0 == result)
			result = Oom_Malloc(n);
		return result;
	}

	static void Deallocate(void *p, size_t /* n */)
	{
		free(p);
	}
	static void(*Set_Malloc_Handler(void(*f)()))()
	{
		void(*old)() = __Malloc_Alloc_Oom_Handler;
		__Malloc_Alloc_Oom_Handler = f;
		return(old);
	}
private:
	static void(*__Malloc_Alloc_Oom_Handler)();
};
template<int inst>
void(*__MallocAllocTemplate<inst>::__Malloc_Alloc_Oom_Handler)() = NULL;


//第二级空间配置
template <bool threads, int inst>
class __Default_Alloc_Template
{
public:
	static void* Allocate(size_t n)
	{
		if (n > __MAX_BYTES)
			return __MallocAllocTemplate<0>::Allocate(n);
		size_t index = FREELIST_INDEX(n);
		void* result = NULL;
		if (free_list[index] == NULL)//如果自由串上没有内存,就去内存池上找空间
			result = Refill(ROUND_UP(n));
		else
		{
			result = free_list[index];
			free_list[index] = free_list[index]->free_list_link;
		}
		return result;
	}
	static void* Refill(size_t n)
	{
		size_t nobjs = 20;
		char * chunk = chunk_alloc(n, nobjs);//通过chunk_alloc函数获得内存
		void* result = (void*)chunk;//把第一个满足的空间分配返回给申请者
		if (nobjs == 1)
			return result;

		//把剩下的多分出的内存空间挂到自由链表上
		else
		{
			size_t index = FREELIST_INDEX(n);
			obj* cur = NULL;
			obj* next = (obj*)((char*)chunk + n);
			free_list[index] = next;
			size_t i = 1;
			for (; i < nobjs; i++)
			{
				cur = next;
				next = (obj*)((char*)next + n);
				cur->free_list_link = next;
			}
			cur->free_list_link = NULL;
		}
		return result;
	}
	static char* chunk_alloc(size_t n, size_t& nobjs)
	{
		size_t totalbytes = n*nobjs;
		size_t poolbytes = _end_free - _start_free;//内存池现有的内存情况
		char* result;//返回分配的内存
		if (poolbytes >= totalbytes)
		{
			result = _start_free;
			_start_free += totalbytes;//降低水位线,内存池内存减少
			return  result;
		}
		else if (poolbytes > n)//内存池满足不了一次分配20个该大小的内存,但至少满足一个(够需求)
		{
			nobjs = poolbytes / n;//当前内存池可满足多少个n
			totalbytes = n*nobjs;
			result = _start_free;
			_start_free += totalbytes;
			return result;
		}
		else
		{//内存池的内存不足

			//重新为内存池申请大小,大小为bytes_to_get
			size_t bytes_to_get = 2 * totalbytes + ROUND_UP(_heap_size >> 4);
			//1、先把内存池中剩余的内存挂到自由链表的相应位置上
			if (poolbytes > 0)
			{
				size_t index = FREELIST_INDEX(poolbytes);
				((obj*)_start_free)->free_list_link = free_list[index];
				free_list[index] = (obj*)_start_free;
			}
			_start_free = (char*)malloc(bytes_to_get);
			if (_start_free == 0)
			{//申请内存失败
				//解决方法:在自由链表上比它大的位置查找是否有空闲内存
				for (size_t i = n; i <= __MAX_BYTES; i += __ALIGN)
				{
					size_t index = FREELIST_INDEX(n);
					obj* p = free_list[index];
					if (p != 0)
					{//找到满足要求的内存
						free_list[index] = free_list[index]->free_list_link;
						_start_free = (char*)p;
						_end_free = _start_free + n;
						return chunk_alloc(n, nobjs);
					}
				}
				//自由链表上没有可提供的内存,就只能转第一种空间配置的方法了
				_start_free = (char*)__MallocAllocTemplate<0>::Allocate(bytes_to_get);
			}
			_heap_size += bytes_to_get;
			_end_free = _start_free + bytes_to_get;
			return(chunk_alloc(n, nobjs));
		}
	}
	static void Deallocate(void*p, size_t n)
	{
		if (n > __MAX_BYTES)
		{
			__MallocAllocTemplate<0>::Deallocate(p, n);
		}
		else
		{
			obj* tmp = (obj*)p;
			size_t index = FREELIST_INDEX(n);
			tmp->free_list_link = free_list[index];
			free_list[index] = tmp;
		}
	}
protected:
	static size_t FREELIST_INDEX(size_t n)
	{
		return (n + __ALIGN - 1) / __ALIGN - 1;
	}
	static size_t ROUND_UP(size_t bytes)//保证字节数与8字节对齐
	{
		return (((bytes)+__ALIGN - 1) & ~(__ALIGN - 1));
	}
private:
	enum { __ALIGN = 8 };
	enum { __MAX_BYTES = 128 };
	enum { __NFREELISTS = __MAX_BYTES / __ALIGN };

	union obj 
	{
		union obj * free_list_link;//下一个节点
		char client_data[1];    /* The client sees this.        */
	};


	//自由链表
	static obj *  free_list[__NFREELISTS];

	//内存池
	static char * _start_free;
	static char * _end_free;
	static size_t _heap_size;//总共为内存池分配的空间字节数
};

template <bool threads, int inst>
typename __Default_Alloc_Template<threads, inst>::obj *   __Default_Alloc_Template<threads, inst>::free_list[__NFREELISTS] = { NULL };


template <bool threads, int inst>
char* __Default_Alloc_Template<threads, inst>::_start_free = NULL;

template <bool threads, int inst>
char* __Default_Alloc_Template<threads, inst>::_end_free = NULL;

template <bool threads, int inst>
size_t __Default_Alloc_Template<threads, inst>::_heap_size = 0;



标题基于Spring Boot的音乐播放网站设计实现研究AI更换标题第1章引言介绍音乐播放网站的研究背景、意义、国内外现状及论文方法创新点。1.1研究背景意义阐述音乐播放网站在当今数字化时代的重要性市场需求。1.2国内外研究现状分析国内外音乐播放网站的发展现状及技术特点。1.3研究方法以及创新点概述论文采用的研究方法及在设计实现上的创新点。第2章相关理论技术基础总结音乐播放网站设计实现所需的相关理论和技术。2.1Spring Boot框架介绍介绍Spring Boot框架的基本原理、特点及其在Web开发中的应用。2.2音乐播放技术概述概述音乐播放的基本原理、流媒体技术及音频处理技术。2.3数据库技术选型分析适合音乐播放网站的数据库技术,如MySQL、MongoDB等。第3章系统设计详细介绍音乐播放网站的整体设计方案。3.1系统架构设计阐述系统的层次结构、模块划分及各模块的功能。3.2数据库设计介绍数据库表结构、关系及数据存储方式。3.3界面设计用户界面的设计原则、布局及交互方式。第4章系统实现详细介绍音乐播放网站的具体实现过程。4.1开发环境工具介绍开发所需的软件、硬件环境及开发工具。4.2核心功能实现阐述音乐播放、搜索、推荐等核心功能的实现细节。4.3系统测试优化介绍系统测试的方法、过程及性能优化策略。第5章研究结果分析呈现音乐播放网站设计实现的研究结果。5.1系统功能测试结果展示系统各项功能的测试结果,包括功能完整性、稳定性等。5.2用户反馈评价收集并分析用户对音乐播放网站的使用反馈评价。5.3对比方法分析将本设计实现其他类似系统进行对比分析,突出优势不足。第6章结论展望总结音乐播放网站设计实现的研究成果,并展望未来发展方向。6.1研究结论概括音乐播放网站设计实现的主要成果及创新点。6.2展望指出当前研究的不足,提出未来改进方向及可
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值