要解决的两个问题:
➢寻找空闲可使用内存块耗费时间不确定 —— 影响实时性
➢ 不断的申请释放会产生很多内存碎片 —— 影响程序运行,甚至死机
这两点对于一个嵌入式实时系统来说都是致命的, 所以需要操作系统采用更加高效、 安全的方式对动态内存空间进行管理。
内存管理器分为动态内存堆管理和静态内存池管理。
内存堆管理算法:内存堆管理用于管理一段连续的内存空间(RAM 中 RW+ZI 段之后一直到 RAM 尾部),
可以根据用户需求分配任意大小的内存块,当用户不再使用时,可以重新释放回堆中。
默认使用的是小内存管理算法:如下rtconfig.h中定义
小内存管理算法:包含一个12字节的数据头。
选择方式:
首先确定系统没有开启(定义)宏 RT_USING_MEMHEAP_AS_HEAP ,然后再判断系统
中是否开启 RT_USING_HEAP 和 RT_USING_SMALL_MEM 来确定是否使用小内存堆管理
算法,在mem.c中判断:
slab算法:多内存池管理快速算法,系统资源比较丰富
[定义在 rtthread.h 中,实现在 slab.c 中]
选择方式:
判断系统中是否开启 RT_USING_HEAP 和 RT_USING_SLAB 来确定是否使用 slab 内
存堆管理算法,
memheap:多内存堆的管理算法。多个地址不连续的内存堆。
[定义在 rtthread.h 中,实现在 memheap.c 中]
选择方式:
判断系统中是否开启 RT_USING_MEMHEAP_AS_HEAP 来确定是否使用 memheap 内存
堆管理算法,
使用内存前,需要系统初始化时堆初始化rt_system_heap_init():
内存堆管理:三种管理算法提供的 API 都是相同的, 在系统运行时选择一种即可,或者直接不
使用 RT-Thread 提供的内存堆管理机制也可以。
分配:从系统堆空间找到合适大小的内存块,把内存块可用地址返回给用户。
释放:如字意。
重分配内存块:在保持原内存块数据不变(缩小时,后面的数据会截断)。
分配多内存块:分配连续内存地址的多个内存块。
设置内存钩子函数:内存分配完成后进行回调。
释放内存钩子函数:释放完回调。
释放内存块后要清空内存块指针,不然会成为野指针。
内存池分配:用于分配大量大小相同的小内存块,尽可能避免内存碎片化。
内存池属于内核对象,支持线程挂起功能
工作机制:通过内存池控制块来实现。
内存池创建时,先向系统申请一大块内存,然后分成同样大小的多个小内存块,链起来(空闲链表),每次分配时,从链头取一个给申请者。
内存池管理:
创建:创建一个内存池对象,并从堆上分配一个内存池。与里面内存块大小,数目匹配。
删除:先唤醒等待在该内存池对象上的所有线程,然后再释放内存池数据存放区域,然后删除内存池对象。
静态:
初始化:由用户指定空间,用户把缓冲区指针传递给内存池控制块。
将内存池对象传给内核,以及内存池用到的内存空间,管理的数据块数目和块大小,指定一个名称,然后初始化。
脱离:先唤醒所有等待在该内存池对象上的线程,然后从内核对象管理器中脱离。
分配:从指定的内存池中分配一个内存块,可设置超时间。
释放:通过释放的内存块计算出内存池对象,增加内存池对象可用内存块数目,把被释放的内存块加入到空闲内存块链表上。
总结: