+-
【C++内存管理】8_G2.9 std::alloc 运行模式概述

概述

free_list 数组总计包含 [0 - 15] 16个元素,其中每个元素分别对应一条子 链表(embedded pointers 组织管理) 每条子链表分别对应管理多个内存块(内存块大小从8字节到128字节)。如,其中free_list[0]管理8字节链表,之后子链表管理的空间大小依次增加 8 字节 当使用者申请内存空间不是8的整数倍时,大小会被调整为8的整数倍再用对应的子链表进行管理 当使用者申请内存大于128字节时,调用 malloc 进行管理内存分配(malloc 意味着 cookie)

示例

第一次申请
客户申请30字节空间,std::alloc调整8字节对齐到32字节,对应 free_list[3] 子链表

free_list[3] 为空,未指向可用内存块节点,调用 malloc 进行大的内存块申请(包含 cookie)

malloc 申请时得到的内存空间:20 x 32 字节内存块 + 20 x 32 字节 战备池 pool 内存块(20数量内存块可能为经验值,由embedded pointers 组织成单链表) 将申请得到的第一个小内存块交给客户进行使用
第二次申请
客户申请72字节空间,atd::alloc 在 free_list[3] 中找到前次申请的 20 x 32 字节战备池空间可用,此空间被重新72字节分割,将第一块传给客户使用
第三次申请
客户申请96字节空间,std::alloc 检查 free_list 无战备池内存可用,于是为 free_list[11] 子链表调用 malloc 进行大的内存块申请【20 x 96 + 20 x 96(对应图中 memory pool)】,将第一块内存块传给客户使用
内存回收
根据回收的内存大小,重新挂载到对应的子链表上(embedded pointers 组织管理)

embedded pointers

下图对应上图某一子链表

union obj {
    union obj *free_list_link;
    char client_data[1];       // 源码中并未使用 client_data, 可忽略理解
}
嵌入式指针,借用内存块前 4 个字节管理可用内存形成单链表【无需占用额外空间,间接说明obj必须 ≥ 4 字节(地址宽度)以用来被指针借用】 容器每次动态分配得到的是一个指针,并不知道此内存是否都带有 cookie(即内部的内存管理方式并不影响客户的使用)