开发指导
使用场景
动态内存管理的主要工作是动态分配并管理用户申请到的内存区间。
动态内存管理主要用于用户需要使用大小不等的内存块的场景。当用户需要使用内存时,可以通过操作系统的动态内存申请函数索取指定大小的内存块,一旦使用完毕,通过动态内存释放函数归还所占用内存,使之可以重复使用。
功能
Huawei LiteOS系统中的动态内存管理模块为用户提供下面几种功能,接口详细信息可以查看API参考。
功能分类 |
接口名 |
描述 |
---|---|---|
初始化和删除内存池 |
LOS_MemInit |
初始化一块指定的动态内存池,大小为size |
LOS_MemDeInit |
删除指定内存池,仅打开LOSCFG_MEM_MUL_POOL时有效 |
|
申请、释放动态内存 |
LOS_MemAlloc |
从指定动态内存池中申请size长度的内存 |
LOS_MemFree |
释放已申请的内存 |
|
LOS_MemRealloc |
按size大小重新分配内存块,并将原内存块内容拷贝到新内存块。如果新内存块申请成功,则释放原内存块 |
|
LOS_MemAllocAlign |
从指定动态内存池中申请长度为size且地址按boundary字节对齐的内存 |
|
获取内存池信息 |
LOS_MemPoolSizeGet |
获取指定动态内存池的总大小 |
LOS_MemTotalUsedGet |
获取指定动态内存池的总使用量大小 |
|
LOS_MemInfoGet |
获取指定内存池的内存结构信息,包括空闲内存大小、已使用内存大小、空闲内存块数量、已使用的内存块数量、最大的空闲内存块大小 |
|
LOS_MemPoolList |
打印系统中已初始化的所有内存池,包括内存池的起始地址、内存池大小、空闲内存总大小、已使用内存总大小、最大的空闲内存块大小、空闲内存块数量、已使用的内存块数量。仅打开LOSCFG_MEM_MUL_POOL时有效 |
|
获取内存块信息 |
LOS_MemFreeBlksGet |
获取指定内存池的空闲内存块数量 |
LOS_MemUsedBlksGet |
获取指定内存池已使用的内存块数量 |
|
LOS_MemTaskIdGet |
获取申请了指定内存块的任务ID |
|
LOS_MemLastUsedGet |
获取内存池最后一个已使用内存块的结束地址 |
|
LOS_MemNodeSizeCheck |
获取指定内存块的总大小和可用大小,仅打开LOSCFG_BASE_MEM_NODE_SIZE_CHECK时有效 |
|
LOS_MemFreeNodeShow |
打印指定内存池的空闲内存块的大小及数量 |
|
检查指定内存池的完整性 |
LOS_MemIntegrityCheck |
对指定内存池做完整性检查,仅打开LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK时有效 |
设置、获取内存检查级别,仅打开LOSCFG_BASE_MEM_NODE_SIZE_CHECK时有效 |
LOS_MemCheckLevelSet |
设置内存检查级别 |
LOS_MemCheckLevelGet |
获取内存检查级别 |
|
为指定模块申请、释放动态内存,仅打开LOSCFG_MEM_MUL_MODULE时有效 |
LOS_MemMalloc |
从指定动态内存池分配size长度的内存给指定模块,并纳入模块统计 |
LOS_MemMfree |
释放已经申请的内存块,并纳入模块统计 |
|
LOS_MemMallocAlign |
从指定动态内存池中申请长度为size且地址按boundary字节对齐的内存给指定模块,并纳入模块统计 |
|
LOS_MemMrealloc |
按size大小重新分配内存块给指定模块,并将原内存块内容拷贝到新内存块,同时纳入模块统计。如果新内存块申请成功,则释放原内存块 |
|
获取指定模块的内存使用量 |
LOS_MemMusedGet |
获取指定模块的内存使用量,仅打开LOSCFG_MEM_MUL_MODULE时有效 |
开发流程
本节介绍使用动态内存的典型场景开发流程。
- 在los_config.h文件中配置项动态内存池起始地址与大小。
配置项
含义
取值范围
默认值
依赖
OS_SYS_MEM_ADDR
系统动态内存起始地址
[0, n)
&m_aucSysMem1[0]
无
OS_SYS_MEM_SIZE
系统动态内存池的大小(DDR自适应配置),以byte为单位
[0, n)
从bss段末尾至系统DDR末尾
无
- OS_SYS_MEM_ADDR:一般使用默认值即可。
- OS_SYS_MEM_SIZE:一般使用默认值即可。
- 执行make menuconfig命令,进入Kernel ---> Memory Management菜单,完成动态内存管理模块的配置。
配置项
含义
取值范围
默认值
依赖
LOSCFG_KERNEL_MEM_BESTFIT
选择bestfit内存管理算法
YES/NO
YES
无
LOSCFG_KERNEL_MEM_BESTFIT_LITTLE
选择bestfit_little内存管理算法
YES/NO
NO
无
LOSCFG_KERNEL_MEM_SLAB_EXTENTION
使能slab功能,可以降低系统持续运行过程中内存碎片化的程度
YES/NO
NO
无
LOSCFG_KERNEL_MEM_SLAB_AUTO_EXPANSION_MODE
slab自动扩展,当分配给slab的内存不足时,能够自动从系统内存池中申请新的空间进行扩展
YES/NO
NO
LOSCFG_KERNEL_MEM_SLAB_EXTENTION
LOSCFG_MEM_TASK_STAT
使能任务内存统计
YES/NO
YES
LOSCFG_KERNEL_MEM_BESTFIT或LOSCFG_KERNEL_MEM_BESTFIT_LITTLE
- 初始化LOS_MemInit。
初始一个内存池后如图,生成一个 EndNode,并且剩余的内存全部被标记为FreeNode节点。注:EndNode作为内存池末尾的节点,size为0。
- 申请任意大小的动态内存LOS_MemAlloc。
判断动态内存池中是否存在申请量大小的空间,若存在,则划出一块内存块,以指针形式返回,若不存在,返回NULL。
调用三次LOS_MemAlloc函数可以创建三个节点,假设分别为UsedA,UsedB,UsedC,大小分别为sizeA,sizeB,sizeC。因为刚初始化内存池的时候只有一个大的FreeNode,所以这些内存块是从这个FreeNode中切割出来的。
当内存池中存在多个FreeNode的时候进行malloc,将会适配最合适大小的FreeNode用来新建内存块,减少内存碎片。若新建的内存块不等于被使用的FreeNode的大小,则在新建内存块后,多余的内存又会被标记为一个新的FreeNode。
- 释放动态内存LOS_MemFree。
假设调用LOS_MemFree释放内存块UsedB,则会回收内存块UsedB,并且将其标记为FreeNode。在回收内存块时,相邻的FreeNode会自动合并。
平台差异性
无。