STL之空间配置器分析

空间配置器
标准规范规定,STL空间配置器是一个名为allocator的模板类,同时也规定了它的必要接口,也就是说allocator类定义形式如下。其中接口allocator::allocate(),
allocator::deallocate(),allocator::construct,allocator::destory()这四个接口及其重要。所以我们这里主要分析这四个接口。
template<class T>
class allocator{

}
SGI STL在这个项目上脱离了STL标准,使用一个专属的,拥有次层分配能力的、效率优越的特殊配置器。其名称为alloc而非allocator,而且不接受任何参数。所有SGI
STL的容器默认的空间配置器为alloc。
一般用new构造一个对象,先要配置内存,然后调用构造函数。用delete删除一个函数,先要将对象析构,然后释放内存。在STL allocator,内存配置由
alloc::allocate()负责,内存释放由alloc::deallocate()负责;对象构造由::construct()负责,对象析构操作由::destroy()负责。
STL配置器定义于<memory>中,SGI <memory>内含两个文件
#include<stl_alloc.h>
#include<stl_construct.h>
<stl_construct.h>中定义了construt()和destroy()两个函数,用来构造和析构对象。其中construt()使用placemen new运算子来完成。destroy()有两个版本,一个版本直接调用
对象的析构函数即可,另一个需要将一个范围的的对象全部析构。但如果在一个范围内析构对象时,析构函数无关痛痒,多次调用析构函数会影响效率,这里destroy()通过
_type_traits<>来解决这个问题。
内存配置和释放是由<stl_construct.h>负责。SGI设计了双层级配置器。第一层直接使用malloc()和free(),第二级则视情况采用不同的策略:当配置区块超过128bytes时
,便调用第一级配置器;当配置器小于128时,采用了复杂的memory pool整理方式。SGI STL默认采用第二级配置器。
第一级配置器主要由__malloc_alloc_template类实现,主要以malloc()、free()、realloc()等C函数执行实际的内存配置、释放、重配置操作,并实现了类似C++ new-handler的机制。当内存配置不足时,会调用oom_malloc()和oom_realloc(),这两个函数在内部不断调用内存不足机制所实现的功能,但如果类似C++ new-handler的机制没有实现具体的例程,便会抛出异常。
第二级配置器定位为__default_alloc_template类,该配置器做法是:如果区块大于128bytes,就调用第一级配置器。当小于128bytes时,则以内存池管理,每次配置一大块内存,并维护对应的自由链表free-lists。下次若再有相同大小的内存需求,就直接从free-lists中拔出。如果客户释放小额区块,就由配置器回收到free-lists中。为了管理方便,
配置器会将主动将任何小额区块的内存需求量上调到8的倍数,并维护16个free-lists,各自管理大小分别为8,16,24,32,40,48,56,83,81,88,96,104,112,120,128bytes的小额区块
。__default_alloc_template该类成员函数allocate()首先判断区块大小,大于128就调用第一级配置器,小于就检查就检查对于的free-list。如果free-list中有可用区块,就直接
拿来用,如果没有可用区块,就将区块大小上调值8的倍数边界,然后调用refill(),准备为free list重新填充空间。Refill()将调用chunk_alloc()从内存中取新的空间给free-list。chunk_alloc()缺省取得20个新的区块给free-list,但如果内存池空间不足,获得的节点数可能小于20。chunk_alloc()函数先判断内存池水量是否充足。如果充足,就直接调用20个区块返回给free list。如果水量不足提供20个区块,但还足够提供一个以上的区块,就拨出这不足20个区块的空间出去。如果内存池连一个区块都无法供应,对客户显然无法交代,此时需要利用malloc()从system heap中配置内存,为内存池注入源头活水以应付需求。新水量的大小为需求量的两倍,再加上一个随着配置次数增加而愈来愈大的附加
量。新水量会将20个区块大小拨给给free list后,将多出来的20多个区块留给内存池。但万一,system heap空间都不够了,malloc()行动失败,chunk_alloc()就会遍历指向比所需区块大的free lists,找到一个就挖出来,找不到就调用第一级配置器,第一季配置器有out-of-memory处理机制(即类似C++ new-handler的机制),利用这种机制或许有机会释放其他的内存拿来此处使用。如果可以就成功,否则发出bad_alloc异常。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值