浅析STL空间配置器

    STL分为6大组件,容器、算法、迭代器、适配器、仿函数、空间配置器;容器距离咱们使用者最近,可是容器之下,是空间配置器。没有空间,不成容器。算法

    STL的空间配置器分类:函数

  1. 一级空间配置器---__malloc_alloc_template
  2. 二级空间配置器--__default_alloc_template

    上图是SGI STL空间配置器的结构,用户调用配置器中的allocate(size_t n)申请内存并返回空间指针,调用deallocate(void *p, size_t n)释放p指向的内存。​​​区块链

一级配置器中的allocate(size_t n):指针

  1.     __malloc_alloc_template中的allocate()直接调用malloc(),若是内存不足则再调用oom_malloc(),不然直接返回
  2. oom_malloc()中不断尝试调用malloc(),而且调用用户设置的处理例程(void (*oom_handler)()),若是用户没有设置处理例程,则跑出异常且exit(0),不然返回得到的空间指针

二级配置器中的allocate(size_t n):调试

  1.     __default_alloc_template中的allocate()判断size是否大于128,大于则转给一配置器中的allocate()处理,不然检查free_list[16]中是否有有适当的区块,存在则从free_list[16]中抽取区块并返回区块指针,不然调用refill()填充free_list[16]并返回获得的第一个区块
  2. refill()直接调用chunk_alloc()从内存池中申请区块,默认申请20个区块,实际得到的区块以参数传回(传址),判断得到的区块是否等于1,若是等于则直接返回区块指针,无须调整free_list[16],不然返回头区块指针,而且将后面的区块连接起来(使用侵入式链表)并挂接到free_list[i]上
  3. chunk_alloc()查看内存池余下空间是否知足20个区块,知足则返回20个区块,不知足则再检查是否知足1个区块以上,知足则返回x个区块,并修改nobjs的值以传出实际返回的区块个数,不然将剩余的区块放入合适的free_list[i]中,再度调用malloc()。成功则返回,失败则检查free_list[16]中是否存在还没有使用的足够区块,存在则回收到内存池中再递归调chunk_alloc(),不然转到一级空间配置器。(PS:返回区块以后须要调整内存池中的头指针---start_free;区块插入到free_list中时用的是头插法)

    如下下是free_list[16]的示意图:code

        

    STL中对于free_list使用了递归

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

来连接区块,由于区块挂接在free_list上时是不存储内容的,因此能够用侵入式链表来连接。此obj直接位于区块的前四字节,存储下一个区块的地址(即next),通过调试,知道client_data此时只是下个区块地址的第一个字节,我暂且认为它在调试的时候起到一个辅助做用(没有找到太可靠的资料来讲明client_data[1])。内存

相关文章
相关标签/搜索