鸿蒙内核源码分析 (TLFS 算法篇) | 图表解读 TLFS 原理
动态分配
本篇开始说一个耳朵听起老茧的概念 动态分配,将分成上下两篇,本篇为上篇,看完能快速理解下篇鸿蒙内核源码对动态内存的具体实现。
- 鸿蒙内核源码分析(TLFS算法) 结合图表从理论视角说清楚 TLFS 算法
- 鸿蒙内核源码分析(内存池管理) 结合源码说清楚鸿蒙内核动态内存池实现过程,个人认为这部分代码很精彩,简洁高效,尤其对空闲节点和已使用节点的实现令人称奇。
TLFS 原理
TLSF(Two-Level Segregate Fit) 是一种用于实时操作系统的内存分配算法,用两级结构对空闲块按大小进行划分,采用两级链表/索引的方式来加快查找。

把上图看懂基本能明白 TLFS 的原理,请尝试自己先理解一遍再看本篇。
解读
- 为方便理解 ,将上图做成(表一),中间过程请查看图表变化

-
右边为第一级链表
First List(简称fl)。将空闲内存块的大小根据2的幂进行分类,如(32、64、128、…), 这跟伙伴算法很类似,伙伴算法是物理内存的分配算法,这样做的好处是防止外部碎片化,是否空闲用位图标识 FL_bitmap | 一维数组,0011代表[32-64]、[64-128]这个区间有内存可以申请,例如: malloc(37) 时,查到在区间[32-64]中,为1代表本次可能可以申请到内存,但具体行不行得进入第二级查看。 -
中间为第二级链表
Second List(简称sl)。第二层链表在第一层的基础上,按照一定的间隔,线性分段,图中将其分成8等份,对于[32-64]来说1/8为4,对于[64 - 128]来说1/8为8,可以确定的是等份也是2的倍数,同样是否空闲用位图标识SL_bitmaps[] | 二维数组 ,每个bit代表是否空闲,图中代表[36 - 39]有内存可供分配,再查看其空闲链表发现真正可供分配的空间有两块,38 和 36,自然将38给 malloc(37) 返回,此时空闲链表中还剩36节点 ,所以 一二级位图数据不会有任何的变化。 -
左边为空闲链表块,上面挂
fl,sl都为1时的空闲内存块,块大小为区间范围值,图中有两个空闲块38b --> 36b,109b --> 104b,在实际运行过程往往出现同样大小的内存块例如38b --> 36b--> 36b
申请过程
用二次申请说明详细过程
- malloc(37) ,发现值在区间
[32-64]并对应fl的位图为1,说明sl中肯定会有一个1,但并不能保证能申请到。得细看第二步sl发现区间[36 - 39]的位图为1,说明空闲链表中肯定会有一块内存,,但也不能保证大小适合37。再看最后一步,发现有两块内存38b --> 36b,只有38b符合,于是 malloc(37) 的结果是获得了一块大小38b的内存块,相差的一个1b称为内部碎片,这种碎片无法避免。将(表一)更新为(表二)

- malloc(50),同样落在
[32-64]查看fl的位图为1,查看第二步sl只有[36 - 39]的位图为1,而 50 > 39,不能满足所以没必要看第三步,得返回第一步往上走发现[64-128]的fl的位图为1,50 < 64 说明 malloc(50) 这次肯定能申请到内存了,查看[64-128]对应的sl发现[104-111]的位图为1,到第三步发现有109b --> 104b两块,选择其中更小104b的块切割成50,54两小块,此时要对54处理挂入空闲链表,54处于fl = [32-64],sl = [52-55]区间,地址为: 0x6838+50=0x686A 。所以将[52-55]区间位图置为1,并挂入空闲链表。将(表二)更新为(表三)

注意此时[32-64]的二级位图变成了 00100010 有两个1
释放过程
同样用二次释放说明详细过程
- free(0x3457) 从地址可知正是上面的 malloc(37)的内存,与分配切割相对应的是释放有合并的步骤,但malloc(37)虽然申请是
37,但其实内核记录的内存块大小是38,所以会找寻地址为 0x3457 + 38 = 0x348F 的地址是否也处于空闲,如果是则合并,由表三可知 并没有 0x348F的空闲块将,而38位于fl = [32-64],sl = [36-39]区间,所以挂回该空闲链表等待后续再分配使用,由此(表三)更新为(表四)

- free(0x5610) 这里假设内核记录该内存块大小为 0x15,归还的同时会找寻0x5610 + 0x15 = 0x5625 是否有空闲块,发现
sl = [104-111]有一块109b空闲块,两块合成一块大小为 109 + 0x15 = 109 + 21 = 130,位于fl = [128-255],sl = [128-143]区间,由此(表四)再更新为(表五)

总结
TLSF(Two-Level Segregate Fit) 有两大优点:
- 实时性,执行速度快,只需查询位图就能知道结果,最多查询两次一级位图,时间复杂度为O(1)。
- 碎片少,浪费少,利用率高,因采用2次幂的方式,切割和合并非常的方便,很少出现外部碎片。
真正的鸿蒙内存动态分配实现过程比这些要复杂些,但有了本文算法基础做铺垫看源码实现会容易很多。
经常有很多小伙伴抱怨说:不知道学习鸿蒙开发哪些技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?
为了能够帮助到大家能够有规划的学习,这里特别整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植等等)鸿蒙(HarmonyOS NEXT)技术知识点。

《鸿蒙 (Harmony OS)开发学习手册》(共计892页):https://gitcode.com/HarmonyOS_MN
如何快速入门?
1.基本概念
2.构建第一个ArkTS应用
3.……

开发基础知识:
1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

基于ArkTS 开发
1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

鸿蒙开发面试真题(含参考答案):https://gitcode.com/HarmonyOS_MN

OpenHarmony 开发环境搭建

《OpenHarmony源码解析》:https://gitcode.com/HarmonyOS_MN
- 搭建开发环境
- Windows 开发环境的搭建
- Ubuntu 开发环境搭建
- Linux 与 Windows 之间的文件共享
- ……
- 系统架构分析
- 构建子系统
- 启动流程
- 子系统
- 分布式任务调度子系统
- 分布式通信子系统
- 驱动子系统
- ……

OpenHarmony 设备开发学习手册:https://gitcode.com/HarmonyOS_MN

写在最后
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
- 想要获取更多完整鸿蒙最新学习资源,请移步前往

更多推荐




所有评论(0)