内存管理
看的是alios things 2.1的代码。个人水平有限,只能粗略讲一下alios things的内存管理。如有错误,请指正。
管理算法
alios things内存管理用到2种管理算法:堆管理和小内存优化算法。
堆管理算法使用配置:RHINO_CONFIG_MM_TLF 1
小内存优化算法配置:RHINO_CONFIG_MM_BLK 1
先进行堆管理内存初始化,初始化后的内存可以这样表示:
| head | firstblk | midblk | lastblk |
|---|
head:头部,保存k_mm_head结构体信息
firstblk:第一个内存块,保存region信息
midblk:中间块,空闲堆。以后申请和释放所使用的内存都是从这里分配出去的。
lastblk:最后一个块,标志region结尾,防止被合并
接着进行小内存算法的初始化,初始化后可以这样表示:
| head | firstblk | pool | midblk | lastblk |
|---|
pool:指的是总体的小内存。实际上pool就是从midblk中分配出来的。整个pool大小由RHINO_CONFIG_MM_TLF_BLK_SIZE决定。而pool又被划分为若干个大小为RHINO_CONFIG_MM_BLK_SIZE的块。
空闲内存链表
经过多次内存申请和释放后,midblk会被分成多个空闲的块。
根据空闲块blk大小分为多个等级的空闲链表,每个等级空闲链表的blk大小在一定范围内:N为等级大小
判断空闲块属于哪个等级的链表依据为:
2^(N + MM_MIN_BIT)
≤ blk_size < 2^(1+N+MM_MIN_BIT)
以空闲链表管理方式优点:减少对大内存块的切割。
申请内存
先判断是否可以从pool申请。若不可以,则根据申请大小size判断其等级,从对应等级的空闲链表找一个大小 >= size的空闲块给它。若找不到,则从上一个有空闲块的空闲链表分配。
快速申请:从上一个等级空闲链表申请,没有则从同等级的空闲链表申请。
快速申请例子:根据图片,比如我要申请一块内存叫needblk,其大小等级符合feelist[5]。普通的申请方式是需要needblk与freelist[5]的空闲块一 一进行大小比较,直到freelis[5]里面有一个块大小大于needblk大小。快速申请直接得到freelist[8]第一个空闲块。
因为freelist[6]和[7]都没有空闲块,所以上一个等级指的是freelist[8]。为什么freelist[8]的第一个一定大于needblk大小,从等级链表的判断依据就可以看出
等级链表依据为(N为等级):
2^(N + MM_MIN_BIT)
≤ blk_size < 2^(1+N+MM_MIN_BIT)
当空闲块大小超过所申请内存块大小一定范围,会对这个空闲块进行切割。切割的一部分分给申请内存,剩下的一部分则放到其大小对应的等级空闲内存链表中。
释放内存
先判断其是否从pool申请的,是则从pool中释放。判断依据为地址。
如果不是,则判断相邻的后一个和前一个blk是否为空闲块。是就合并再释放。
| 前一个blk | 所释放的blk | 后一个blk |
|---|
若前一个blk和后一个blk都为空闲块,没有分配出去。则这3个blk会和并成一个新的空闲blk,新的空闲blk大小为这3个blk大小之和。然后放到对应等级的空闲链表中。