STL六大组件 之 空间配置器

空间配置器存在的原因:

①频繁的申请和释放空间,就会频繁地调用malloc和free函数,函数调用时栈帧的开辟和回退,这些都是有开销的,就会降低运行的效率。

②频繁的申请和和释放空间,会造成内存碎片的问题。使得即使有足够的空间,也申请不到一个连续的空间。

 

SGI 标准的空间配置器:std::allocator, 它符合部分标准,但效率不佳,它只是把以下两个函数::operator new(只分配内存)和::operator delete(只回收内存)做了一层薄薄的包装而已(一般不使用)。

SGI 特殊的空间配置器:std::alloc 配置器定义在<memory>之中,SGI<memory>内包含两个文件:

 

1、#include<stl_alloc.h>   定义了一、二级配置器,负责内存空间的内配和释放,配置其名为alloc。

一级配置器:template<int inst>

class _malloc_alloc_template{…};

         其中:①allocate()直接使用malloc();deallocate()直接使用free()。

                    ②模拟C++的set_new_hander()以处理内存不足的情况。

二级配置器:template<bool threads,int inst>

class _default_alloc_template{…};

其中:①维护16个自由链表(free lists),负责维护16种小型区块的次配置能力。

                                     内存池(memory poll)以malloc()配置而得。

                                     如果内存不足,转调用第一级配置器(那儿有处理程序)。

②如果需求区块大于128bytes,就调用一级配置器。需求区块小于128bytes时,采用内存池整理方式,不再求助于一级配置器。

       对于是只开放一级配置器,还是同时开放二级配置器,取决于_USE_MALLOC是否被定义(如果定义:一级配置器;否则:二级配置器)

       在这两个配置器之上还有一层包装:simple_alloc ,使alloc具备标准接口。

SGI STL 容器的定义中默认使用二级空间配置器。

整个空间配置过程以一个例子说明:

       当vector需要扩容时,有三个步骤:1.重新配置空间,2.将原空间数据复制到新分配的空间,3. 释放原空间

在第一步重新配置空间中,就需要通过空间配置器去进行空间分配。

具体:

1、需配置空间大小n大于128字节,调用一级配置器进行分配。

2、需配置大小n小于128字节:

(1)在二级配置器维护的16个链表(free_list)中找到对接近n且大于n的区块链表,从这个区块中拔出首区块分配出去。

(2)如果free_list中没有合适区块了,则从内存池中分配空间给free_list(默认为20*k)

(3)如果内存池中也没有空间了,则从heap中malloc所需区块大小(以(2)中的默认大小为准)的2倍+附加量给内存池,在递归调用自己重新给free_list分配

(4)如果malloc失败,则从free_list上未使用且足够大的区块中找一块去配置所需区块,再去给用户分配空间

(5)如果free_list中也没有未使用的区块了,则调用一级配置器。因为以及配置器有out_of_memory机制,可以去处理分配失败问题,有机会释放其他的内存拿来此处用,如果失败,发出bad_alloc异常。

 

2、#include<stl_construct.h>    定义了construct() 和destroy(),都是全局函数,负责对象的构造和析构。

猜你喜欢

转载自blog.csdn.net/Dxiaoru/article/details/81415090
今日推荐