STL空间配置器:
1.空间配置器为什么不叫内存配置器:
配置的空间可以是内存也可以是硬盘,但是SGI STL的空间配置器是内存
2.1标准空间配置器:std::allocator
配置器是默认选项:vector的声明如下:template
class vctor{...}
比如在vs2010中定义一个vector对象:vector
标准配置器很少使用,因为效率低,只是用allocate和deallocate对::operator new和::operator delete进行了一层简单封装,
返回分配空间指向的指针
2.2特殊空间配置器:std::alloc
效率高,原因是将上面new中步骤分解为两步:1.内存配置,alloc::allocate() 2.对象构造,::construt(),
(delete同理,先::destroy(),后alloc::deallocate)
内存配置在
2.3 std::alloc详解:空间配置和释放
空间分配需要考虑:
1.向system heap要求空间
2.内存不足怎么办
3.过多小型区域造成的内存碎片(双层级配置器,第一级使用malloc()和free(),第二级后面解释)
tips:c++的内存配置操作是::operator new()和::operator delete(),实际上使用c的malloc()和free()完成内存配置和释放
双层级配置器策略:
1>需要的内存大于128bytes时,调用第一级配置器,直接使用malloc()和free()配置
2>需要的内存小于128B时,为了减少过多的内存碎片,使用第二级配置器,内存池方式分配
默认同时开启第一二级,且将alloc封装成simple_alloc来适应stl标准
第一级配置器:__malloc_alloc_template
第一级直接使用malloc,free,realloc配置,allocate()封装了malloc和oom_malloc,
正常调用malloc分配空间,但当内存不足时,调用oom_malloc(),oom_malloc有内循环,
不断调用内存不足处理程序(若用户没设定,直接丢bad_alloc异常,或exit(1)直接中止),直到成功分配
第二级配置器:__default_alloc_template
维护16个free-lists(8~128,都是8的倍数)(如果申请额空间不是8的倍数,自动补上)
每个结点定义如下:union obj{
union obj* free_list_link;
char client_data[1];};
为了维护链表,每个结点需要free_list_link来指向下一个结点,不是也会浪费空间么?
解决:结点定义如上,使用union,公用空间,提高效率,在非强型语言(c++)中很普遍,强型(java)不可以
class __defaulta_alloc_template{
......
static char *start_free;//内存池起始位置
static char *end_free;
static heap_size;
allocate(n);//>128,调用第一级配置器, 否则找对应的free_list,若找不到对应的free_list则重新填充free list
};
每个free_list指向一些区块,比如free_list[2]指向的区块大小为24,可以有n个
若对应的free_list没有区块可以用了,则调用refill()
refill新的空间将取自内存池(调用chunk_alloc),默认一次获得20个新区块
chunk_alloc(size ,nobjs) size为所需要的区块大小,nobjs为返回给对应free list的个数(默认为20个)
内存池通过end_free-start_free来判断内存池的水量,分3种情况:
1.若水量充足,就直接调出20个区块,第一个交给客户端,剩下的19个交个对应的free list维护
2.若可以提供一个以上,但<20个区块,就返回实际可提供的区块,nobjs更新为实际返回区块数
3.一块都提供不了,内存池耗尽,此时用malloc从system heap中配置空间,1个交给客户端,19个区块交给对应free list,剩下的交给内存池