【STL源码解析】空间适配器allocator(三)第二级空间配置器

本文深入解析STL中的二级空间配置器,它采用内存池设计,通过自由链表减少小空间分配时的额外开销。详细介绍了内存分配、释放及内存池的工作原理,阐述了如何在free_list中管理和填充空间。
摘要由CSDN通过智能技术生成


前言

在上一篇博文中介绍了第一级空间配置器 ,在第一级空间配置器中,本质上还是使用的malloc来进行空间分配。如果分配的空间较小的时候,使用malloc会导致cookie这些额外空间开销过大(这里可以参考【内存管理】模块的博文)。因此SGI采用二级空间配置器去避免较大的额外开销,更加充分的利用好内存空间。下面介绍第二级空间配置器。


一、二级空间配置器__default_alloc_template

二级空间配置器采用了内存池的设计,整个设计让人看了觉得特别有意思~

1、设计思路:
(1)当分配较多较小空间的内存的时候,每个小空间都带有cookie(纪录当前内存块的大小)等额外空间。因此考虑将cookie采用共用的形式,多个同样大小的小空间共用一个cookie。
(2)采用内存池进行内存的分配和回收。内存池通过自由链表去实现。STL中用free_list去表示这块内存空间。
(3)如果采用链表去分配空间的话,需要使用指针去指向下一个位置,那么就会产生内存消耗。为了节省内存空间,STL中采用union(嵌入式指针)。【嵌入式指针可以参考模块对应的博文】

//这个结构就相当于把一块内存区域复用:(1)数据存储的块(2)块位置的下一个位置
union obj{
   
	union obj * free_list_link; //这个应该表示的是free_lists自由链表上某一块区域的下对应的指针
	char client_data[0]; //这个应该表示的是用户需要存储的数据
}

关于其中的一些问题&个人理解:
(1)用free_list[i]就是一个上面union结构,其中用嵌入式指针存储了自由链表free_list中第i块下的链表。

下面是第二级空间配置器的部分实现:

//enum是表示枚举值
enum {
   __ALIGN = 8}; //小型区块的上调边界
enum {
   __MAX_BYTES = 128}//小型区块的上限。对于区块大于128的直接采用一级空间配置器
enum {
   __NFREELISTS = __MAX_BYTES / __ALIGN}; //free_list的个数

//以下是第二级空间配置器
//无template类型参数,不考虑多线程的情况
template <bool threads, int inst>
class __default_alloc_template{
   
private:
	//ROUND_UP将bytes上调至8的倍数
	//这个是为了字节对齐
	static size_t ROUND_UP(size_t bytes){
   
		return (bytes + __ALIGN - 1) & ~(__ALIGN - 1); //没太懂,8是1000,8 - 1 = 7 也就是 111
		//这里一般来说上调至8的倍数,应该是 n + (8 - n%8)
	}
	
	union obj{
   
		union obj *free_list_link;
		char client_data[1];
	}
	
	static obj* volatile free_list[__NFREELISTS]; //自由链表数据
	static size_t FREELIST_INDEX(size_t bytes){
   
		return (((bytes) + __ALIGN - 1) /  __ALIGN - 1);
	}

	static void *refill(size_t n);
	
	//配置一大块空间,可容纳nobjs个大
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值