stl第二级空间配置器 __defult_alloc_template

之前说了第一级的空间配置器。这里再说一下第二级。
我们知道大于128字节的内存分配交给第一级,小于128级的交给第二级。

第二级空间配置器增加了一些机制来避免太多的小额区块造成的内存碎片。并且太多的小内存碎片对系统性能来说也是一种负担。为什么这么说呢?
因为我们每分配一块内存,都得有一些税交给系统,里面记录了该区块的大小。内存越小,税就相对越大。

那么第二级空间配置器的做法是:
小于128的内存需求给内存池管理,此法也称为次层配置。每次配置一块大内存,并维护一个自由链表
为了方便管理,SGI配置器会将需求调成8的倍数,比如需要30字节,分配32字节。自由链表分成16个,分别管理8,16,…,128字节大小的内存需求。如果下次有相等大小的需求,则从对应链表拨出,同时,内存释放时回收到自由链表中。所以,配置器不仅负责分配,还负责回收。

自由链表的节点结构如下:
在这里插入图片描述
大家会有疑惑,节点必须分配额外的指针,这不是负担吗?其实早就解决了这个问题。我们注意这个union,这表示联合,里面可以放很多类型的变量。union的长度在于最长变量的长度。union中所有变量是共享内存的,在obj中也就是一物二用。从第一个变量看,obj指向另一个obj,从第二个字看,obj指向实际内存区块。这种技巧在强型语言行不通比如JAVA。
分配内存块节点A时,原来指向A的指针指向它的下一个内存块节点,该A块放入用户的数据。

怎么分配呢?比如一次需求为96字节
1、如果对应的自由链表不为空。则直接分配;
2.如果对应的自由链表为空,则从内存池中申请20个大小为96字节的节点。如果内存池不足20个,则拿出一个给用户,其余尽可能多的放到该链表中。
3、如果内存池连一个大小为96的节点都无法满足,则使用malloc函数为内存池在堆上申请内存。
4、如果申请失败,说明堆上也没有足够的空间分配了。则会从大于96的链表中拨出一个节点使用。
5、如果大于96的链表节点都没有的话,就调用终极办法----一级空间配置器函数oom-allocate函数。

好了,到现在,我们明白了stl中内存空间是如何分配的。目的是减少内存碎片,以及减少malloc系统调用,增加系统性能。对于小块内存,我们使用内存池管理,因为内存池是连续分配的一块空间,不会产生很多内存碎片。虽然内部碎片无可避免。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值