堆的动态存储分配之分离适配(Segregated fit)

有关动态存储分配的文献描述了几十种 分离存储方法。

主要的区别在于

如何定义大小类。 何时进行合并。 何时向操作系统请求额外的堆存储器。 是否允许分割。

我们介绍两种基本的方法

简单分离存储(simple segregated storage)和分离适配(segregated fit)。

简单分离存储

大小类

每个大小类的空闲链表包含大小相等的块,每个块的大小就是这个大小类中最大元素的大小。

例如,{17~32}中,这个类的空闲链表全是32的块。

如何分配

检查相应大小最接近的空闲链表

如果非空,简单的分配其中第一块的全部。

不用分割,是全部哦

如果为空,请求一个固定大小的额外存储器片,将这个片分割,然后加入对应的链表。

然后继续跳回非空执行。 常数级

如何释放

直接释放即可,然后分配器将释放后的块直接插入空闲链表。 常数级

不分割,不合并。

已分配块不需要头部。 都不需要脚部。

最显著的缺点

很容易造成内部碎片和外部碎片

分离适配

分配器维护着一个空闲链表的数组。

每个空闲链表是和一个大小类相关联的,并且被组织称某种类型的显示或隐式链接。 每个链表包含潜在的大小不同的块。

这些块的大小是大小类的成员。

有许多种不同的分离适配分配器,这里介绍一个简单版本。

如何分配

对适当的空闲链表做首次适配。

成功

那我们(可选的)分割它。 并将剩余部分插入到适当的空闲链表。

失败

继续找空闲链表 如果找遍了都没有,就请求额外的堆存储器。

释放,合并。

释放一个块,并执行合并,存入相应的空闲链表。

分离适配方法是一种常见的选择,C标准库提供的GUN malloc包就是采用的这种方法。

快速

搜索时间少 对存储器的利用率高

对分离空闲链表简单的首次适配搜索,其存储器利用率近似对堆的最佳适配搜索。

3. 伙伴系统

伙伴系统(buddy system)是分离适配的一种特例,其中每个大小类都是2的幂。

大小类

都是2的幂,最大为2^m

如何分配

请求块大小向上舍入到最接近的2的幂,假设为2^k。 在空闲链表中找到第一个2^j,满足(k<=j<=m) 二分变成2^(j-1) 和 2^(j-1) 两部分,其中半块丢入空闲链表中。

两者互相为伙伴。 不断上面步骤,直到j=k。 复杂度O(log(m)),很低

如何释放,合并

释放时,递归合并。

给定地址和块的大小,和容易计算它的伙伴地址。 如果伙伴处于空闲就不断合并,否则就停止。 复杂度O(log(m)),很低。

伙伴系统分配器的主要

优点

它的快速搜索和快速合并。

缺点

要求块大小为2的幂可能导致显著的内部碎片。 不适合通用目的的工作负载。

对于预先知道其中块大小是2的幂的系统,伙伴系统分配器就很有吸引力。


原文完整链接:https://www.2cto.com/kf/201605/511876.html

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值