---- 整理自狄泰软件唐佐林老师课程
文章目录
- 1. 讨论
- 2. 动态内存管理
- 2.1 动态内存管理的关键
- 2.2 动态内存管理的分类
- 3. 定长内存管理的设计与实现
- 3.1 空间划分
- 3.2 内存申请和归还
- 3.3 关键数据类型
- 3.4 思考
- 4. 变长内存管理的设计与实现
- 4.1 空间划分
- 4.2 内存申请和归还
- 4.3 关键数据类型&初始化
- 4.4 编程实验:变长内存管理
- 5. 问题
- 5.1 D.T.OS中的策略
- 5.2 D.T.OS架构图
- 5.3 D.T.OS内存布局
- 5.4 编程实验:D.T.OS中的动态内存分配
- 6. 扩展讨论
- 7. 小结
1. 讨论
- 开发操作系统不能使用malloc()动态内存分配吗?
- 不是不能,而是没有!malloc()作为系统函数需要实现才能有,目前的D.T.OS还没有实现
- 那么如何 实现malloc() 呢?
- 动态内存管理的本质 是一个算法设计问题
2. 动态内存管理
- 根据需要分配内存和回收内存
通常在一块较大且连续的内存空间上进行分配和回收 - 动态内存管理解决的问题
内存资源稀缺,通过内存复用增加任务的并发性 - 动态内存管理的本质
时间换空间,通过动态分配和回收 “扩大” 物理内存
2.1 动态内存管理的关键
- 时间效率
从发出内存申请到获得内存的时间越短越好 - 空间效率
为了管理内存而占用的内存越少越好 - 碎片化
最大可分配内存占空闲内存总和的比例越大越好
2.2 动态内存管理的分类
- 定长内存管理
将内存分为大小相同的单元,每次申请一个单元的内存 - 变长内存管理
每次申请需要的内存(大小不固定,以字节为单位)
3. 定长内存管理的设计与实现
3.1 空间划分
将内存分为两部分:管理单元 & 分配单元
- 管理单元与分配单元一一对应
- 将管理单元组织成链表(定长内存管理链表)
- 管理内存时操作链表头
3.2 内存申请和归还
- 申请内存
- 从链表头获取一个管理单元,并计算下标
- 根据下标计算分配单元的内存起始地址
- 归还内存
- 计算分配单元的下标,并将对应下标的管理单元插入链表
3.3 关键数据类型
void FMemInit(byte* mem, uint size)
- 初始化内存管理,从mem中构建管理单元和分配单元
void* FMemAlloc()
- 动态申请 一个内存单元,失败时返回NULL
int FMemFree(void* ptr)
- 归还申请的单元,成功时返回1,失败时返回0
【参看链接】:58-59-60 - 动态内存分配的实现 / 58
3.4 思考
- 定长内存管理能够满足开发需要吗?
4. 变长内存管理的设计与实现
4.1 空间划分
将内存分为三部分:管理头 & 已用区域 & 空闲区域
- 管理头:记录已用区域和空闲区域的位置
- 已用区域:已分配的内存区域(使用中)
- 空闲区域:可分配的内存区域(空闲)
4.2 内存申请和归还
管理结点构成管理链表:
- 申请内存
- 初始时只有一个管理结点(used == 0,free == all)
- 每次申请时从管理结点查找可用内存(alloc <= free)(alloc包含 管理头的内存 和 申请的内存)
- 划分可用内存成为新的管理结点(used == size,free == 0)
- 将管理结点组织成管理链表
- 归还内存
- 遍历管理链表,找到对应的目标管理结点
- 将目标管理结点从管理链表中移除
- 目标管理结点所占用的内存归入前一个管理结点的空闲区域中(新管理结点是插入在管理链表中部)
4.3 关键数据类型&初始化
管理结点中的管理头:
- 初始化管理链表:
void* VMemAlloc(uint size)
动态申请size字节内存,失败时返回NULLint VMemFree(void* ptr)
归还申请的内存单元,成功时返回1,失败返回0
4.4 编程实验:变长内存管理
【参看链接】:58-59-60 - 动态内存分配的实现 / 59
5. 问题
- void* Malloc(uint size) 函数如何具体实现?
5.1 D.T.OS中的策略
- 内存申请
- 内存归还
5.2 D.T.OS架构图
5.3 D.T.OS内存布局
5.4 编程实验:D.T.OS中的动态内存分配
【参看链接】:58-59-60 - 动态内存分配的实现 / 60
6. 扩展讨论
- 变长内存管理法从结点空闲区域的尾部划分内存,为什么?
- void* Malloc(uint size)函数的效率怎么样?
- 再回过头考虑:
- 内存越界运行却没有错,为什么?
- malloc(0)返回什么,是NULL吗?
- free(NULL)为什么不会出问题?
7. 小结
- 动态内存管理是 在一块连续的内存空间上进行分配和回收
- 动态内存管理通常分为 定长管理法和变长管理法
- 定长内存管理法高效但不灵活
- 变长内存管理法灵活但不高效
- Malloc() / Free()结合使用定长管理法和变长管理法的优势,在效率和灵活性上达到了平衡