从以下间断步骤中,咱们能够理解到 alloc 工作时的根本流程。其中蕴含战备池、自在链表每次最多新增 20 个区块、追加量、碎片解决、内存不足时的解决等概念
起始
- free_list 数组蕴含 16 个元素,子元素别离治理不同内存大小的自在链表(单链表)
第一次内存申请
- 分配器的客户是容器,即分配器服务于容器
- 应用 malloc 申请的内存大小可能不同,因而须要借助 cookie 记录大小信息以进行后续的内存开释动作
- 容器的所有元素大小已知且统一,因而能够不应用 malloc(不应用 cookie)
- 在 alloc 工作时,总是先把可用内存放到战备池,再从战备池切割适当的内存到 free_list 治理的链表
补充形容
- 容器申请 32 bytes, 因为 pool(战备池)为空,故应用 malloc( 蕴含 cookie)索取内存并胜利向 pool 加注 32 x 20 x 2 + RoundUp(0>>4) = 1280 bytes,从中切出 1 个区块返回给容器,19 个区块给 list#3, 残余 640 bytes 备用(战备池)
- 战备池:由 start_free、end_free 指针形容
RoundUp (0>>4) : 追加量,会越来越大
RoundUp : 是一个函数,将一个数值(累计申请总量)调整到 16 的边界
0 >> 4 : 0(目前的申请总量,首次值 0)/ 16
无文档可阐明为什么须要应用追加量,且每次追加量值是累计申请量除以 16,或者为经验值
第二次内存申请
补充形容
- 圆滑连接线示意图中内存块在地址上间断
- 直角连接线示意图中内存块在自在链表中间断
第三次内存申请
第四次内存申请
补充形容
- 通过以上操作,代码中曾经创立了 4 种容器,每个容器大小各不相同,由图中的 4 条链表进行别离治理
- 总计应用两次 malloc
第五次内存申请
第六次内存申请
第六次内存申请
补充形容
- 通过以上操作,代码中曾经创立了 7 中容器,每个容器元素大小各不相同,由图中的 7 条链表进行别离治理
- 总计应用三次 malloc
- 特地阐明, 如果多种容器(vector、list、queue、deque)它们所治理的对象大小雷同,此时会共用同一条子自在链表
第七次内存申请
第八次内存申请
第九次内存申请
第十次内存申请
补充形容
-
图中 free_list[8] 和 free_list[9] 为虚线,示意空链表(指向 null),无可用内存块
- free_list[9] 因为内存块被回填战备池以供应 alloc 应用
- free_list[8] 因为惟一内存块被应用返给客户
第十一次内存申请
第十二次内存申请
产生的纳闷
补充形容
-
检讨 1 技术难点:
- 如何找到自在链表中适合大小且内存相邻的两个或多个节点进行合并
- 不晓得链表的长度,尤其内存块一直动静被申请又被回收
- 检讨 2 后续解说