LiteOS内存管理
1、内存管理简介
内存管理模块管理系统的内存资源,它是操作系统的核心模块之一。
主要包括内存的初始化、分配以及释放。
在系统运行过程中,内存管理模块通过对内存的申请/释放操作,来管理用户和OS对内存的使用,使内存的利用率和使用效率达到最优,同时最大限度地解决系统的内存碎片问题。
LiteOS的内存管理分为静态内存管理和动态内存管理,提供内存初始化、分配、释放等功能。
2、 运作机制-动态内存
动态内存管理,即在内存资源充足的情况下,从系统配置的一块比较大的连续内存(内存池) ,根据用户需求,分配任意大小的内存块。当用户不需要该内存块时,又可以释放回系统供下一次使用。
与静态内存相比,动态内存管理的好处是按需分配,缺点是内存池中容易出现碎片。
LiteOS动态内存支持DLINK和BEST LITTLE两种标准算法。
1、DLINK动态内存管理结构如下图所示:
第一部分: 堆内存(也称内存池)的起始地址及堆区域总大小。
第二部分: 本身是一个数组,每个元素是一个双向链表,所有free节点的控制头都会被分类挂在这个数组的双向链表中。每次申请内存的时候,会从这个数组检索最合适大小的free节点,进行分配内存。每次释放内存时,会将该片内存作为free节点存储至这个数组,以便下次再利用。
第三部分: 占用内存池极大部分的空间,是用于存放各节点的实际区域。
2、BEST LITTLE动态内存管理
1)LiteOS的动态内存分配支持最佳适配算法,即BEST LITTLE,每次分配时选择内存池中最小最适合的内存块进行分配。LiteOS动态内存管理在最佳适配算法的基础上加入了SLAB机制,用于分配固定大小的内存块,进而减小产生内存碎片的可能性。LiteOS内存管理中的SLAB机制支持可配置的SLAB CLASS数目及每个CLASS的最大空间。
2) 每次申请内存时,先在满足申请大小的最佳SLAB CLASS中申请,(比如用户申请20字节内存,就在SLAB块大小为32字节的SLAB CLASS中申请),如果申请成功,就将SLAB内存块整块返回给用户,释放时整块回收。如果满足条件的SLAB CLASS中已无可以分配的内存块,则继续向内存池按照最佳适配算法申请。需要注意的是,如果当前的SLAB CLASS中无可用SLAB块了,则直接向内存池申请,而不会继续向有着更大SLAB块空间的SLAB CLASS申请。
3)释放内存时,先检查释放的内存块
是否属于SLAB CLASS,如果是SLAB CLASS的内存块,则还回对应的SLAB CLASS中,否则还回内存池中。
3、 运作机制-静态内存
1 、 静态内存实质上是一块静态数组,静态内存池内的块大小在初始化时设定,初始化后块大小不可变更。
2 、 静态内存池由一个控制块和若干相同大小的内存块构成。控制块位于内存池头部,用于内存块管理。内存块的申请和释放以块大小为粒度。
4、 内存的应用场景与开发流程
(1)动态内存使用场景:
1、内存管理的主要工作是动态的划分并管理用户分配好的内存区间。
2、动态内存管理主要是在用户需要使用大小不等的内存块的场景中使用。
3、当用户需要分配内存时,可以通过操作系统的动态内存申请函数索取指定大小内存块,一旦使用完毕,通过动态内存释放函数归还所占用内存,使之可以重复使用。
(2)静态内存使用场景:
当用户需要使用固定长度的内存时,可以使用静态内存分配的方式获取内存,一旦使用完毕,通过静态内存释放函数归还所占用内存,使之可以重复使用。
(3)动态内存开发流程:主要介绍BEST LITTLE开发流程
1、配置:
LOSCFG_MEMORY_BESTFIT:置为YES,选中内存管理算法中的BESTFIT算法。
LOSCFG_KERNEL_MEM_SLAB:置为YES,打开内存管理中的SLAB机制。
2、初始化:
调用函数初始化用户指定的动态内存池,若用户使能了SLAB机制并且内存池中的可分配内存大于SLAB需要的最小内存,则会进一步初始化SLAB CLASS。
3、申请任意大小的动态内存:
调用函数从指定的内存池中申请指定大小的内存块,申请时内存管理先向SLAB CLASS申请,申请失败后继续向堆内存空间申请,最后将申请结果返回给用户。在向堆内存空间申请时,会存在内存块的切分。
4、释放动态内存:
调用函数向指定的动态内存池释放指定的内存块,释放时会先判断该内存块是否属于SLABCLASS,若属于,则将该内存块还回SLAB CLASS。否则,向堆内存空间释放内存块。在向堆内存空间释放时,会存在内存块的合并。
(4)静态内存开发流程:
1、规划一片内存区域作为静态内存池。
2 、系统内部将会初始化静态内存池。
将入参指定的内存区域分割为N块(N值取决于静态内存总大小和块大小),将所有内存块挂到空闲链表,在内存起始处放置控制头。
3、系统内部将会从空闲链表中获取第一个空闲块,并返回该块的用户空间地址。
4、将该块内存加入空闲块链表。
5、系统内部清零静态内存块,将入参地址对应的内存块清零。
注意事项:
静态内存池区域,可以通过定义全局数组或调用动态内存分配接口方式获取。如果使用动态内
存分配方式,在不需要静态内存池时,注意要释放该段内存,避免内存泄露。
5、操作系统抽象层简介
OSAL的API内存管理接口:
接口名 | 功能描述 |
---|---|
osal_malloc | 按字节申请分配动态内存空间 |
osal_free | 释放已经分配的动态内存空间 |
osal_zalloc | 按字节申请分配动态内存空间,分配成功则初始化这块内存所有值为0 |
osal_realloc | 重新申请分配动态内存空间 |
osal_calloc | 申请分配num个长度为size的动态内存空间 |
申请动态内存:void *osal_malloc(size_t size);
释放动态内存:void osal_free(void *addr);
申请且初始化动态内存为0:void *osal_zalloc(size_t size);
重新申请分配动态内存:void *osal_realloc(void *ptr,size_t newsize);
申请分配n个长度为size的动态内存空间:void *osal_calloc(size_t n, size_t size);
6、 实现内存管理功能
/* 使用osal接口需要包含该头文件 */
#include <osal.h>
static int mem_access_task_entry()//任务入口函数
{uint32_t i = 0; //循环变量size_t mem_size; //申请的内存块大小uint8_t* mem_ptr = NULL; //内存块指针while (1){mem_size = 1 << i++; //每次循环将申请内存的大小扩大一倍mem_ptr = osal_malloc(mem_size);//尝试申请分配内存if(mem_ptr != NULL){printf("access %d bytes memory success!\r\n", mem_size); // 申请成功osal_free(mem_ptr);//释放申请的内存,便于下次申请mem_ptr = NULL;//将内存块指针置为NULL,避免称为野指针printf("free memory success!\r\n");}else{/* 申请失败,打印信息,任务结束 */printf("access %d bytes memory failed!\r\n", mem_size);return 0;} }
}int standard_app_demo_main()
{osal_task_create("mem_access_task",mem_access_task_entry,NULL,0x400,NULL,11);return 0;
}
每循环一次,动态申请的内存空间就扩大一倍,系统启动后,串口shell的优先级为10,最先打印shell信息,接下来内存申请任务创建开始执行,不断增大内存的申请空间,在芯片STM32L431芯片上最大能申请的空间为16384 字节,即16KB。
7、 思考
- 应用其他接口函数继续实验,会有什么现象?
- 内存管理有哪些优势?
- 内存管理在实际项目开发中应用有哪些?
LiteOS内存管理相关推荐
- LiteOS 内存管理
参考: [野火]物联网操作系统 LiteOS 开发实战指南 Huawei LiteOS | 中文网 8. 内存管理 8.1 基本概念 8.1.1 概念 LiteOS操作系统将内核与内存管理分开实现,操 ...
- 华为liteos内存管理源码以及架构分析
文章目录 华为liteos内存管理源码以及架构分析 牵扯到的主要数据结构 华为liteos内存管理源码以及架构分析 本文主要从源码层面讲解华为针对物联网的一个小型操作系统liteos的内存管理方式: ...
- 从结构体、内存池初始化到申请释放,详细解读鸿蒙轻内核的动态内存管理
摘要:本文带领大家一起剖析了鸿蒙轻内核的动态内存模块的源代码,包含动态内存的结构体.动态内存池初始化.动态内存申请.释放等. 本文分享自华为云社区<鸿蒙轻内核M核源码分析系列九 动态内存Dyna ...
- 操作系统的内存管理算法
关注.星标公众号,不错过精彩内容 转自:LiteOS物联网操作系统 本文主要介绍内存的基本概念以及操作系统的内存管理算法. 一.内存的基本概念 内存是计算机系统中除了处理器以外最重要的资源,用于存储当 ...
- jar包部署shell脚本编写,在服务器上部署jar包,在Linux服务器上部署服务,设置编码格式,设置内存管理
准备步骤: 1.安装java环境,知道java安装目录 2.将jar包拖放或发送至服务器中(目录自定义) 一.编写shell脚本,将以下代码放在shell脚本中,将shell脚本放在jar包同级目录下 ...
- 垃圾回收 内存管理 python
20220225 https://mp.weixin.qq.com/s/94SmSNEkwmz-Eu-hBUo0Lg Python的内存管理机制 在windows 中直接在任务管理其中关掉python ...
- BEP 7:CUDA外部内存管理插件(下)
BEP 7:CUDA外部内存管理插件(下) Numba依赖 向库中添加EMM插件的实现自然会使Numba成为库的依赖项,而以前可能没有.为了使依赖关系可选,如果需要的话,可以有条件地实例化并注册EMM ...
- BEP 7:CUDA外部内存管理插件(上)
BEP 7:CUDA外部内存管理插件(上) 背景和目标 在CUDA阵列接口使得能够共享不同的Python之间的数据库的访问CUDA设备.但是,每个库都与其它库区别对待.例如: • Numba在内部管理 ...
- Objective C内存管理之理解autorelease------面试题
Objective C内存管理之理解autorelease Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的Aut ...
最新文章
- 2019年Reddit机器学习板块17个最佳项目:最新代码、资源应有尽有
- qt4.8创建.pri_注意Java 8的[Pri​​mitive] Stream.iterate()中的递归
- EntityFramework Core映射关系详解
- jquery插件整理篇(六)HTML编辑器插件
- struts-step
- 设计模式之观察者模式PHP实现
- 一款简单实用的iOS分享框架(支持三方登陆)
- win7系统删除多余的系统服务操作
- linux ubuntu安装教程 pdf,Ubuntu下安装PDF阅读器Okular
- hotmail邮箱pop3server设置方法
- Jquery UI中 Dialog对象的作用及常用属性
- JavaScript给按钮绑定点击事件(onclick)的方法及js常见事件
- “打怪升级”,电竞浪潮中一家非典型公司的生存之道
- electron项目打包报错
- Linux列出磁盘信息
- 京东X未来餐厅正式开业,无界零售布局再进一步
- linux 文件转utf 8,在Linux系统下把文件转换为UTF-8编码
- 钉钉官方接口调用过程
- 应用篇:三角函数与反三角函数的应用
- 简易的第三方组件日志脱敏