STL之空间配置器分析

来源:互联网 发布:淘宝上架宝贝软件 编辑:程序博客网 时间:2024/06/01 08:32
空间配置器
标准规范规定,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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 钢笔替换芯干了怎么办 水芯钢笔不出水怎么办 被红斑蛇咬了怎么办 狗生完小狗不爰吃饭怎么办 比熊见了狗就叫怎么办 小狗到新主人家里吐怎么办 床上有小绿叶蝉怎么办 腰椎间盘轻微突出怎么办 养的小白兔死了怎么办 小鸡嘴边起很大的疙瘩怎么办 兔子下牙齿断了怎么办 刚种的花蔫了怎么办 鲜切花花朵蔫了怎么办 兔子扭伤脚肿了怎么办 兔子的耳朵肿了怎么办 家里养兔子大了怎么办 幼兔不吃兔粮怎么办 大兔子咬小兔子怎么办 买的小兔子拉稀怎么办 半个月的小兔子怎么办 母兔下崽没奶怎么办 母松鼠下崽后没有奶怎么办 母猫下崽后小猫没奶吃怎么办 母兔产后没奶水怎么办 兔子生崽了不管怎么办 兔子下小兔不管小兔怎么办 兔子下小兔示喂奶怎么办 兔子生完小兔不喂奶怎么办 小兔子生宝宝了怎么办 人摸了小兔崽怎么办 狗狗尿道有脓怎么办 笼养母兔下崽了怎么办 小羊羔站不起来怎么办 兔子不让小兔子吃奶怎么办 兔子不吃东西没精神怎么办 母兔没有初奶怎么办 兔子只喝水不吃东西怎么办 兔子不吃东西也不喝水怎么办 兔子怀孕后不爱吃东西喝水怎么办 母兔产仔无奶怎么办 仔兔十五天母兔没奶怎么办