【转】|【STL二级空间配置器的原理剖析和简单实现】

通俗易懂的一篇博文
复习时拿来看了
原文链接---->二级空间配置器的原理剖析和简单实现

二级空间配置器结构

SGI对空间的分配与回收就是以“哈希桶”的方式,不过在此并没有把它就做“哈希桶”,而是自由链表(free_lists),为了方便管理,SGI二级配置器会主动将任何小额区块的内存需求量上调至8的整数倍,所以自由链表中管理的空间大小为分别为(8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128 字节)

在这里插入图片描述

分配法则

SGI空间配置器分两级,大于128字节的使用一级空间配置器,小于等于128字节的使用二级空间配置器。那么,空间分配函数第一步要干的事就是判断申请空间的大小,然后根据大小来确定分配空间的方式(使用一级空间配置器还是二级空间配置器的方式),在这里只讨论使用二级空间配置器的情况,即申请的字节数小于128。

下边以申请12字节的空间为例讲解一下二级空间配置器处理空间申请的过程-------12字节会被上调到8的整数倍,也就是16.

首先去对应自由链表里边找(通过字节数16对齐到计算出对应位置为1号自由链表),看自由链表对应位置有没有空间,如果有,就采用头删的方式将自由链表上挂接的第一个空间结点分配给用户使用,然后将剩下的空间继续挂接起来空间申请就结束了,简单又高效。但是如果0号自由链表中没有空间,就需要去内存池里边申请了,如果就向内存池申请一块 16个字节的空间,下一次申请16字节空间的时候自由链表中依然是没有空间,又要到内存池里边申请,每次都这样,很麻烦,所以,在向内存池里申请空间的时候,不是一次只申请一块16个字节的空间,而是多申请几块16字节的空间(比如20块),方便下一次 16字节空间的申请。

到内存池里边申请空间,又有三种情况,第一种情况:内存池里边空间还很足,16字节大小的空间还可以分配出20块,那么,将其中1块分配给用户使用,然后将剩下的19块挂接到自由链表中,下一次申请16字节的空间就可以直接在自由链表中取了。第二种情况:内存池里边空间不是很足,不能一次性提供 20 个块 16个字节的空间,但是可以提供5块 16字节的空间(不一定是5 ,只要比20小,大于等于1就行),那么,就将能提供的这5块空间的其中一块返回给用户使用,剩下的4块挂接到自由链表中;第三种情况:内存池里的空间已经很紧张了,假如只剩下8个字节,连一块16字节的空间都提供不了了,那么这个时候就需要朝系统去申请空间来填充内存池了,由于管理内存池的就是一个_start 和 _end 指针,只能标记上一块连续的空间,所以,之前内存池中还剩的8个字节的空间就需要将它挂接到对应的自由链表(也就是0号自由链表)中,然后向系统申请一端空间放入到内存池中,并用_start 和 _end 指针将这段空间标记管理起来。这就回到了第一种情况。

向系统申请一大块空间就一定能申请成功么?不一定,如果系统里边的空间也已经不足了就会申请失败,这个时候,就需要向自由链表后边管理的比16字节大的空间里边去切割了,因为不确定那个自由链表里有空间,所以,需要遍历管理自由链表的数组,在遍历的时候有一个小细节,目前我们申请的16字节的空间对应的是1号自由链表,按理说我们应该从2号自由链表开始查找,但是由于需要考虑多线程,(有可能在我们向内存池或系统申请空间的时候,另一个线程已经归还空间并挂接到了1号自由链表中),所以,依然从1号自由链表开始遍历。当遍历到某个自由链表(假如是3号自由链表中管理的有空间),那么,就从3号自由链表中取一个空间结点下来(同样是以头删的方式)放入到内存池中,然后再使用在内存中申请空间的方式申请空间就OK了

如果一直将后边全部的自由链表都遍历完了,也没有找到一块空间。也就是说所有自由链表、内存池、系统里都不能提供空间,可以说是山穷水尽了。空间都去哪了?已经分配给用户了,那么,只能调用一级空间配置器,因为一直空间配置器在无法分配空间的时候会调用用户设置的内存释放函数,将自己已经不用的空间归还给系统,这样就有可能还能申请到空间,如果用户没有设置内存释放函数的话,那么申请空间的结果就只能是失败(抛异常)了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值