《STL源码剖析》STL的双层配置器

SGI STL第一级配置器:

template<int inst>
class __malloc_alloc_template{...};
其中:
1.allocate()直接使用malloc(),deallocate()直接使用free().
2.模拟C++的set_new_handler()以处理内存不足的情况.

SGI STL第二级配置器:

template<bool threads,int inst>
class _default_alloc_template{...};
其中:
1.维护16个自由链表(free lists),负责16种小型区块的次配置能力.
内存池以malloca()配置而得.如果内存不足,专用第一级配置器(那儿有处理程序)
2.如果需求区块大于128bytes,就转调用第一级配置器.

不管使用的是第一级配置器还是第二级配置器,都是用malloc()实现的。

第一级配置器

第一级配置器以malloc(),free(),realloc()等C函数执行实际的内存配置和释放,冲配置操作,并实现出累死C++ newhandler的机制,是的,它不能直接运用C++new-handler机制,因为它并非 使用::operator new来配置内存。(所谓C++new handler机制是,你可以要求系统在内存配置需求无法被满足时,调用一个你所指定的函数)
SGI第一季配置器的allocate()和realloc()都是在调用malloc()和realloc()不成功后,改调用oom_malloc()和oom_realloc(),后两者都有内循环,不断调用“内存不足处理例程”,期望在某次调用后,获得足够的内存而圆满完成任务,但如果“内存不足例程”未被客端设定,oom_malloc()和oom_realloc()便老实不客气地调用_THROW_BAD_ALLOC,丢出bad_alloc异常信息,或者利用exit(1)中止程序。

第二级配置器

SGI第二级配置器的做法是,如果区块够大,超过128bytes时,就移交第一级配置器处理,当区块小玉128bytes时,则以内存池(memory pool)管理,此法又成为次层配置:每配置一大块内存,并维护对应之自由链表。下次若再有相同大小的内存需求,就直接从free-lists中取出,如果客端释还小额区块,就由配置器回收到自由链表中,为了方便管理,SGI第二级配置器会主动将任何小额区块的内存需求量上升至8的倍数(例如客端要求30bytes,就自动调整为32bytes),并维护16个free-lists,各自管理大小分别为8,16,24,32,40,48,56,64。。。128bytes的小额区块,自由链表的结点结构如下:

union obj{
    union obj *free_list_link;
    char client _data[1];
};//使用union节省内存

空间配置函数allocate()

身为一个配置器,_default_alloc_template拥有配置器的标准接口函数allocate(),此函数首先判断区块的大小,大于128bytes就调用第一级配置器,小玉128bytes就检查对应的自由链表,如果没有可用的区块,就将区块大小上调至8的倍数边界,然后调用refill()准备为free list重新填充空间。

https://github.com/li-zheng-hao
原文地址:https://www.cnblogs.com/lizhenghao126/p/11053751.html