当前位置: 首页 > news >正文

HCIA-HarmonyOS设备开发认证V2.0-轻量系统内核内存管理-动态内存

在这里插入图片描述

目录

  • 一、动态内存运行机制
  • 二、动态内存开发流程
  • 三、动态内存使用说明
  • 四、动态内存核心算法
  • 五、动态内存接口
  • 六、代码分析(待续...)
  • 坚持就有收获

一、动态内存运行机制

动态内存管理,即在内存资源充足的情况下,根据用户需求,从系统配置的一块比较大的连续内存(内存池,也是堆内存)中分配任意大小的内存块。当用户不需要该内存块时,又可以释放回系统供下一次使用。

二、动态内存开发流程

  • 初始化 LOS_MemInit。初始一个内存池后生成一个内存池控制头、尾节点 EndNode,剩余的内存被标记为 FreeNode 内存节点。注:EndNode 作为内存池末尾的节点,size 为0。
  • 申请任意大小的动态内存 LOS_MemAlloc。判断动态内存池中是否存在大于申请量大小的空闲内存块空间,若存在,则划出一块内存块,以指针形式返回,若不存在,返回NULL。如果空闲内存块大于申请量,需要对内存块进行分割,剩余的部分作为空闲内存
    块挂载到空闲内存链表上。
  • 释放动态内存 LOS_MemFree。回收内存块,供下一次使用。调用 LOS_MemFree 释放内存块,则会回收内存块,并且将其标记为 FreeNode。在回收内存块时,相邻的FreeNode 会自动合并。

三、动态内存使用说明

  • 由于动态内存管理需要管理控制块数据结构来管理内存,这些数据结构会额外消耗内存,故实际用户可使用内存总量小于配置项 OS_SYS_MEM_SIZE 的大小。
  • 对齐分配内存接口 LOS_MemAllocAlign/LOS_MemMallocAlign 因为要进行地址对齐,可能会额外消耗部分内存,故存在一些遗失内存,当系统释放该对齐内存时,同时回收由于对齐导致的遗失内存。
  • 非连续性内存区域接口 LOS_MemRegionsAdd 的 LosMemRegion 数组参数传入的非连续性内存区域需要按各个内存区域的内存开始地址升序,且内存区域不能重叠。

四、动态内存核心算法

TLSF:Two-Level Segregated Fit 两级分割策略算法.

OpenHarmony LiteOS-M动态内存在TLSF算法的基础上,对区间的划分进行了优化,获得更优的性能,降低了碎片率。动态内存核心算法框图如下:
请添加图片描述

根据空闲内存块的大小,使用多个空闲链表来管理。根据内存空闲块大小分为两个部分:[4, 127]和[27, 231],如上图size class所示:

  • 对[4,127]区间的内存进行等分,如上图绿色部分所示,分为31个小区间,每个小区间对应内存块大小为4字节的倍数。每个小区间对应一个空闲内存链表和用于标记对应空闲内存链表是否为空的一个比特位,值为1时,空闲链表非空。[4,127]区间的内存使用1个32位无符号整数位图标记。

  • 大于127字节的空闲内存块,按照2的次幂区间大小进行空闲链表管理。总共分为24个小区间,每个小区间又等分为8个二级小区间,见上图蓝色的Size Class和Size SubClass部分。每个二级小区间对应一个空闲链表和用于标记对应空闲内存链表是否为空的一个比特位。总共24*8=192个二级小区间,对应192个空闲链表和192/32=6个32位无符号整数位图标记。

例如,当有40字节的空闲内存需要插入空闲链表时,对应小区间[40,43],第10个空闲链表,位图标记的第10比特位。把40字节的空闲内存挂载第10个空闲链表上,并判断是否需要更新位图标记。当需要申请40字节的内存时,根据位图标记获取存在满足申请大小的内存块的空闲链表,从空闲链表上获取空闲内存节点。如果分配的节点大于需要申请的内存大小,进行分割节点操作,剩余的节点重新挂载到相应的空闲链表上。

当有580字节的空闲内存需要插入空闲链表时,对应二级小区间[29,29+2^6],第31+2*8=47个空闲链表,第2个位图标记的第17比特位。把580字节的空闲内存挂载第47个空闲链表上,并判断是否需要更新位图标记。当需要申请580字节的内存时,根据位图标记获取存在满足申请大小的内存块的空闲链表,从空闲链表上获取空闲内存节点。如果分配的节点大于需要申请的内存大小,进行分割节点操作,剩余的节点重新挂载到相应的空闲链表上。如果对应的空闲链表为空,则向更大的内存区间去查询是否有满足条件的空闲链表,实际计算时,会一次性查找到满足申请大小的空闲链表。

五、动态内存接口

功能类别接口函数描述
初始化和删除内存池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时有效

六、代码分析(待续…)

坚持就有收获

在这里插入图片描述

相关文章:

  • 在PyTorch中,如何查看深度学习模型的每一层结构?
  • [高并发] - 1.高并发综述
  • 代码随想录算法训练营第三十四天|860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球
  • 有了NULL,为什么C++还需要nullptr?
  • Educational Codeforces Round 135 (Rated for Div. 2)C. Digital Logarithm(思维)
  • 书生浦语-模型微调
  • 用HTML和CSS打造跨年烟花秀视觉盛宴
  • 新的风口:继ChatGPT热潮后,OpenAI又推出视频生成新浪潮
  • 【AIGC】Stable Diffusion介绍
  • nginx upstream server主动健康监测模块添加https检测功能
  • 拿捏c语言指针(上)
  • 【微服安全】API密钥和令牌与微服务安全的关系
  • Windows 环境下 Redis 的安装和基本使用
  • Arduino ESP8266/ESP32 TCP/UDP通讯例程
  • 嵌入式——Flash(W25Q64)
  • php的引用
  • [译] React v16.8: 含有Hooks的版本
  • 【mysql】环境安装、服务启动、密码设置
  • Github访问慢解决办法
  • JS笔记四:作用域、变量(函数)提升
  • MySQL用户中的%到底包不包括localhost?
  • Netty+SpringBoot+FastDFS+Html5实现聊天App(六)
  • Rancher如何对接Ceph-RBD块存储
  • React Transition Group -- Transition 组件
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • Theano - 导数
  • Vue 2.3、2.4 知识点小结
  • 扑朔迷离的属性和特性【彻底弄清】
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • 消息队列系列二(IOT中消息队列的应用)
  • 移动端唤起键盘时取消position:fixed定位
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • ()、[]、{}、(())、[[]]命令替换
  • (30)数组元素和与数字和的绝对差
  • (70min)字节暑假实习二面(已挂)
  • (c语言)strcpy函数用法
  • (k8s中)docker netty OOM问题记录
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (分享)自己整理的一些简单awk实用语句
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (六)软件测试分工
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (四)库存超卖案例实战——优化redis分布式锁
  • (学习日记)2024.02.29:UCOSIII第二节
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (最全解法)输入一个整数,输出该数二进制表示中1的个数。
  • ***监测系统的构建(chkrootkit )
  • .net MySql
  • .Net Web项目创建比较不错的参考文章
  • .NET 中什么样的类是可使用 await 异步等待的?
  • .NET 中使用 Mutex 进行跨越进程边界的同步
  • .Net(C#)常用转换byte转uint32、byte转float等