STL---空间配置器

     空间配置器是STL六大组件之一,它的作用就是为STL中的容器提供高效的管理空间,虽然我们平时没有使用过,但是其存在于每个容器上。因为STL所操作的对象(数值,键值对)都存放在容器当中,当增加新的对象(数值,键值对)时,都是通过new申请的,但有很多不足,

1.频繁的向内存申请小块的内存块,容易造成内存碎片,并且影响运行效率
2.直接使用malloc和new申请一段连续空间,都会有额外的浪费(32+4)bytes
    32是一个结构体,为了管理空间,是一个双向链表的方式   4是用来检测是否越界的

因此就需要设计高效的内存管理机制:空间配置器。

空间配置器分为一级空间配置器和二级空间配置器,都是用来处理空间分配的,在SGI-STl中是以128bytes为界限的,一级空间配置器处理128bytes以上的大块内存,二级空间配置器处理128bytes以下的小块内存

一级空间配置器:

一级空间配置器(__malloc_alloc_template)的原理很简单,直接对malloc和free进行了封装:

public:
// 对malloc的封装
static void * allocate(size_t n)
{
    //申请空间成功,直接返回,失败交由oom_malloc处理
    void *result = malloc(n);
    if (0 == result)
        result = oom_malloc(n); //oom_mallloc是用来解决内存不足        
    return result;
}
以上若是result==0意味着系统空间不足,就进入oom_malloc函数,这个函数会调用应对措施:(*my_malloc_handler)();申请空间

//对free的封装
static void deallocate(void *p, size_t /* n */)
{
    free(p);
}

二级空间配置器:

     相对于一级空间配置器的对于malloc和free的重新封装,二级空间配置就相对的复杂了一些。二级空间配置器在SGI_STl中采用了内存池的技术提高申请空间的效率和减少额外空间的浪费,并且采用哈系桶的方式来提高对空间的管理。

     内存池:顾名思义就是用来存放内存的池子,需要一块空间的时候直接在池中取就行了,当池中的空间不够,再向内存中取,当用户不用时,直接将空间还回给内存池中即可。提高了效率,解决了内存碎片和额外浪费的问题。

     哈系桶:利用哈系桶将用户归还的内存块管理起来,方便下一次使用同大小的内存时,先从桶中查找是否有合适的。规定以8的整数倍来管理申请(释放)内存块,但为什么不用链表来管理(因为链表的查找效率低)。

           

如上图,用户调用二级空间适配器申请空间时调用时,工作方式是:1.先检测用户所需要的空间是否小于128bytes,不是交给一级空间适配器处理。2.根据申请空间的size计算出对应空间的桶号。3.检测桶中是否有内存块,有头删该内存交给用户,没有从内存池中截取size大小放入桶中。

    在内存池中截取内存size大小内存块时,调用函数,一次性向内存池索要20个n大小的空间,若只有一个n大小的内存块,将桶中的第一个返回给用户,其他块连接在桶上。若内存池空间不足以提供至少一块n大小的内存,要向内存池中补充空间,先将内存池中小块挂到对用桶中,向系统堆申请内存填充内存池,申请成功,继续chunk_alloc;失败,将桶中比size大的内存块交给内存池,继续chunk_alloc,再失败的话,就要向一级空间适配器求助。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值