1

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

 2 years ago
source link: https://segmentfault.com/a/1190000040037054
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

【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)

image.png

第一次申请

  • 客户申请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

下图对应上图某一子链表

image.png

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

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK