STL二级空间配置器简述

二级空间配置器:

二级空间配置器对内存的管理减少了小区块造成的内存碎片,它主要是:如果所要申请的空间大于128字节,则直接交至一级空间配置器处理,如果小于128字节,则使用二级空间配置器,它是用一个16个元素的自由链表来管理的,每个位置下挂载着大小(分别为8、16、24、32、48、56、64、72、80、88、96、104、112、120、128字节),每次将所需内存提升到8的倍数。
free_list它的节点结构为一个共用体:

union obj
{
    union obj * free_list_link;
    char client_data[1];
};

这是sgi stl中的问题。首先,要弄清楚使用的场景,STL在第二级配置器中的内存池中用到自由链表。用上述union结构,可以做到仅用一个指针的大小来存放两个信息:一是自由链表的下一个节点;二是自由链表当前节点指向的实际内存空间。client_data可以理解成一个常量指针,当最初赋值的时候,client_data指向实际内存空间,然后再给free_list_link赋值,此时注意由于union的特性,只会修改client_data[0]的大小,即数组中保存的值,client_data还是指向实际内存空间。换句话说,数组指向实际内存空间,数据的值为多少不影响。

STL空间配置器的union obj讲解

二级空间配置器的结构图:


image

个人理解:
free_list_link本身是下一个节点的地址,但其指向的值(*free_list_link)是对应其挂载的相同大小的存储空间。

if(n > __MAX_BYTES)          //所需内存是否大于128bytes,如果大于128bytes则调用以及空间配置器。
{
    return malloc_alloc::allocate(n);
}
//如果小于128bytes,调用二级空间配置器并找出16个free_list中时当的一个
my_free_list = free_list + FREELIST_INDEX(n);      
result = *my_free_list;
//如果free_list中为空则准备填充(填充函数就如下面几种情况,下面会详细解释)
if(result == 0
{
    void *r = refill(ROUND_UP(n));   
    return r;
}
//相应free_list有自由区块则调整free_list,拔除一个节点分配出去。
*my_free_list = result->free_list_link;
return result;

使用STL二级空间配置器的流程


image

你可能感兴趣的:(STL二级空间配置器简述)