边界标识法——分配和回收

本文介绍了边界标识法在操作系统中的应用,作为动态分区分配的一种存储管理方法。内容涵盖边界标识法的结点结构,首次拟合法、最佳拟合和最差拟合的分配与回收算法。在分配时,首次拟合从链表头查找,最佳拟合按大小排序,而最差拟合从最大结点分配。回收时,通过检查相邻内存区域的边界标识进行合并。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

预备知识

(1) 首次拟合 从表头指针查找,找到的第一个大小不小于m的结点的一部分分配给用户。

分配时需要查找可利用空间表,回收时直接插到表头即可。

(2) 最佳拟合 将可利用空间表中一个不小于m且最接近m的空闲块的一部分分配给用户,推荐按结点从小到大排序,回收时把释放的空闲块插入到合适的位置上。

最佳拟合法适用于请求分配的内存大小范围较广的系统。
最佳拟合无论分配回收都需要查找可利用空间表,因此最费时间

(3) 最差拟合 将可利用空间表中不小于n且是链表中最大的空闲块的一部分分配给用户,此时结点应当从大到小排序,分配时只需从链表中删除第一个结点,并分配一部分给用户,剩余部分插入到合适位置。

最差拟合每次从最大结点分配,最终结点大小趋于一致,适用于内存大小范围较窄的系统。
最差拟合分配时直接表头分配,回收时需要把空闲块插入在合适位置上,因此需要查找链表。

边界标识法

边界标识法是操作系统中用以动态分区分配的一种存储管理方法,系统将所有空闲块连接在一个双重循环链表结构的可利用空间表中。

边界标识法结点结构

每个内存区头部和底部设标识,标识该区域是占用块(1)还是空闲块(0),使得在回收用户释放的空闲块时易于判别在物理位置上与其相邻的内存内存区域是否为空闲块,以便合并空闲存储区。

//space指示存储单元,单元大小由head中的size域表示,以head和foot作为边界,head和foot中都有标志域tag
typedef struct WORD
{
    union
    {                 //head和foot分别是节点的的第一个字和最后一个字
        WORD *llink;  //头部域,指向前驱结点
        WORD *uplink; //底部域,指向本节点头部,大小随size改变
    };
    int tag; //0空闲1占用,后部和尾部均有
    int size;
    WORD *rlink;            //头部域,指向后继结点
    OtherType other;        //字的其他部分
} WORD, head, foot, *Space; //*Space可利用空间指针类型

#define FootLoc(p) p + p->size - 1 指向p所指结点的底部

首次拟合法分配

找到表头指针所指结点起在可利用空间表中查找,找到第一个容量不小于请求分配的存储量的空闲块就进行分配
(1)如果待分配块容量为m个字,每次分配分配n个字给用户,剩余m-n大小的结点仍然留在链表中(剩余容量极小的块)
解决方法:设定一个e,m-n<e时,就将m整块分配给用户,反之分配高地址的n个字给用户(避免修改指针)
(2)如果每次分配都从表头指针开始找的话,会使得存储量小的结点密集在头指针附近,所以每次查找应当从不同结点开始查找,实现方法是使头指针指向刚分配过结点的后继结点

#define e 40
Space AllocBoundTag(Space &pav, int n)
{
   
   
    //若有不小于n的空闲块则分配相应的存储块,返回首地址;
    //若分配后表不空,则pav指向表中刚分配过的结点的后继结点
    WORD *p = NULL,*f=NULL;
    for (p = pav; p->size < n && p->rlink != pav; p = p->rlink)
        ; // p->rlink!=pav,循环链表的头
    if (!p || p->size < n)
        return NULL;
    else
    {
   
   
        f = 
### SLAB/SLUB/SLOB 分配器工作机制原理详解 #### 1. SLAB 分配器工作原理 SLAB 是 Linux 内核早期实现的一种高效的小型对象管理机制。它主要解决的是以字节为单位的内存分配需求,避免直接使用伙伴系统造成的内存碎片化问题。 - **基本概念**: SLAB 将一组连续的物理页面划分为多个固定大小的对象池(object pool),并预先初始化这些对象以便快速分配回收[^3]。 - **核心结构**: SLAB 使用 `struct kmem_cache` 来描述一个缓存实例,该结构体包含了关于对象大小、对齐方式以及其他元数据的信息[^1]。 - **着色技术**: SLAB 利用剩余空间进行所谓的“着色”,即调整对象在内存中的起始地址偏移量,使得不同对象能够映射到 CPU 缓存的不同行,从而提升硬件缓存命中率并降低冲突概率[^2]。 - **分配流程**: 当应用程序请求一块特定大小的内存时,SLAB 首先查找是否存在合适的已有的缓存实例;如果没有,则创建一个新的缓存实例,并从底层伙伴系统获取足够的页面资源填充此缓存[^3]。 --- #### 2. SLUB 分配器工作原理 SLUB 是一种改进版的 SLAB 实现,其设计目标在于简化内部逻辑的同时保持高性能表现。 - **无全局锁的设计**: 不同于传统 SLAB 的复杂锁定机制,SLUB 借助每个 CPU 上独立维护的一组局部变量来减少争用情况的发生,这极大提高了多处理器环境下的并发性能[^1]。 - **通用性灵活性增强**: SLUB 支持动态配置各种属性(比如调试标志位等),并且允许开发者灵活定义新的缓存类别而不必担心兼容性问题[^1]。 - **内存利用优化**: 它通过更精细地控制每页所能容纳的最大对象数量以及合理安排自由列表指针等方式进一步减少了因边界效应而导致的空间浪费现象[^1]。 - **分配过程概述**: 对于小型内存请求而言,通常会优先尝试满足来自当前节点上的某个活动 slub 中未使用的 slot;一旦发现某 slub 已满载则触发新 slub 创建操作直至最终完成整个分配动作为止[^4]。 --- #### 3. SLOB 分配器简介 SLOB 是专门为嵌入式设备定制的一个极其简单的内存分配方案,适用于那些运行环境中可用 RAM 总量非常有限的情形下。 - **适用场景**: 主要用于低功耗单板计算机或其他受限平台之上,在这类场合往往无承受额外开销较大的常规 slab 或者 slub 方案所带来的负担。 - **运作模式**: 只简单区分两大类区域——大块区 (large block area) 小块区(small block areas),前者针对大于 PAGE_SIZE 的请求处理,后者负责其余较小尺寸范围内的分配任务[^3]。 - **优势特点**: 极大地降低了代码复杂度与执行时间成本,同时保留了一定程度的功能完备性足以应对大多数实际应用需求[^3]。 --- ### 结论 综上所述,三种分配器各有侧重领域及其独特之处:SLAB 注重全面功能覆盖及高度可调节能力;SLUB 更加关注易用性与效率平衡之间的取舍关系;而 SLOB 则完全偏向轻量化方向发展以适应特殊计算条件的要求。选择具体哪一款取决于具体的项目背景技术指标考量因素。 ```c // 示例代码展示如何通过 kmalloc 接口间接调用 SLAB/SLUB 分配器 void* ptr = kmalloc(64, GFP_KERNEL); if (!ptr) { printk(KERN_ERR "Memory allocation failed\n"); } else { memset(ptr, 0, 64); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值