10-1RT-Thread动态内存管理

news2024/9/23 13:30:49

10-1RT-Thread动态内存管理
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在嵌入式系统中,变量和中间数据一般存放在系统存储空间中。只有在实际使用时,才将它们从存储空间读取到CPU进行运算。存储空间可分为两种,内部存储空间rem和外部存储空间rome或flash。其中ram或称之为内存,访问速度比较快,可以按照变量地址随机访问,但断电后数据会丢失。而room或flash的内容比较固定,主要用来保存程序本身的数据内容,保存的内容断电后不会丢失。

对于嵌入式的内存又有堆和栈之分栈不需要程序员手动去申请。函数的局部变量入参都占用空间,当函数执行结束时,占空间会自动释放,而堆需要程序员手动申请和释放。

在RT thread中有两种堆内存管理方式,动态内存堆管理和静态内存池管理。

在这里插入图片描述
1.一般内存管理算法是根据需要存储数据的长度,在内存中寻找一个与这段数据相适应的空闲内存块,然后存储数据。而寻找空闲内存块耗费的时间是不确定的这对实时操作系统来说是不可接受的。因此实时操作系统必须保证内存块的分配过程是在可预测的确定时间内完成。

2.随着内存不断被分配和释放,整个内存区域会产生越来越多的碎片。系统中虽有足够的空间块,但他们的地址并非连续,导致无法申请到大的内存。对于通用系统而言,可以通过重启系统解决,但对于嵌入系统来说可能无法接受。

3.嵌入式系统的资源不同,内存在KB到MB之间,如何为系统选择高效率的内存分配算法比较复杂。

在这里插入图片描述
在这里插入图片描述
在RT thread中将ZI段结尾处到内存尾部的空间作为内存堆,主要用于系统动态分配内存的场合。比如我们使用动态方式创建某些内核对象,如消息队列、邮箱、信号量等的时候,所使用的内存空间就是动态内存堆。

动态内存管理是在内存资源充足的情况下,根据用户的需求,从系统配置的一块比较大的连续内存中分配任意大小的内存块,当用户不需要该内存时,又可以释放供系统再进行统一的管理。其优点是按需分配,在设备中使用灵活。缺点是内存容易碎片化。

RT thread 关于动态内存堆的管理主要有三种算法
在这里插入图片描述
我们只能通过RT thread settings来配置系统内核,选择其中一种内存管理方法。对于用户而言,这三种算法是透明的,也就是说提供给用户的内存管理接口是相同的,只是算法的实现原理不同。

在这里插入图片描述
当需要分配内存时,将从这个大的内存块上分割出相匹配的内存块,然后把分割出来的空闲内存块还给堆管理系统。

每个内存块不管是已分配的内存块还是空闲的内存块,都包含一个数据头,通过这个头把使用块与空闲块用双向链表的方式链接起来。

Magic不仅仅用于标识这个数据块,是一个内存管理用的内存数据块,实质也是一个内存保护字,如果这个区域被改写,那么也就意味着这个内存块被非法改写,在正常情况下,只有内存管理器才会去碰这块内存

那么小内存管理是如何进行内存分配的呢?
在这里插入图片描述
我们假设此时空闲链表指针初始指向32字节的内存块,当用户线程要分配一个64字节的内存块时,由于当前指针内存块只有32个字节,并不满足要求,内存管理器会继续寻找下一个内存块。在此例中,当找到128字节时,它是满足分配要求的。但因为这个内存块比实际需求大,分配器会把内存块进行拆分,剩余的内存块继续留在列表中。
在这里插入图片描述
每次分配内存块前都会留出12个字节的数据头,用于magic use的信息及链表节点使用。返回给应用的地址实际上是这块内存块12字节以后的地址,而数据头部分是用户永远不应该改变的部分。

在这里插入图片描述
Slab分配器会根据对象的大小分成多个区,也可以看成每类对象有一个内存池,一个zone的大小在32K到128K字节之间。分配器会在堆初始化的时候,根据堆的大小自动调整系统中的作用。最多包含72种对象,一次最大能够分配16K的内存空间。如果超出16K那么直接从一页分配器中分配。

每个作用上分配的内存块大小是固定的,能够分配相同大小内存块的作用会链接在一个链表中,而72种对象的zoo列表则放在一个数组zone arry中统一管理flag管理算法主要有内存分配和内存释放两个过程。

在这里插入图片描述
对于内存分配,我们假设分配一个32字节的内存slab,内存分配器会先按照32个字节的值,从zoo的arry链表表头数组中找到相应的zone链表。如果这个链表是空的,则向液分配器分配一个新的rom,然后从rom中返回第一个空闲块。如果链表非空,则这个作用链表中第一个zone节点必然有空闲块存在,那么就取相应的空闲块。如果分配完成后,zone中所有的空闲内存块都使用完毕,那么分配器需要把这个zone节点从列表中删除,而内存的释放是分配器需要找到内存块中所在的zone节点,然后把内存块链接到zone的空闲内存块链表中。如果此时zone的空闲列表指示出zone的所有内存块都已释放,即zone是完全空闲的,那么当作文列表中全空闲作用达到一定数目后,系统就会把这个全空闲的作用释放到页面分配器

在这里插入图片描述
memheap管理算法适用于系统中包含多个地址不连续的内存堆,使用memheap内存管理可以简化系统存在多个内存堆时的使用。当系统中存在多个内存堆的时候,用户只需要在系统初始化的时候,将多个所需的memheap初始化,并开启memheap功能,就可以很方便的把多个memheap粘合起来,用于系统的的P分配。memheap工作机制如图所示,首先将多块内存加入memheap_item链表进行粘合。当分配内存时会先从默认内存堆中分配内存,当分配不到时会查找memheap_item列表,尝试从其他的内存堆上分配内存块。应用程序不用关心当前分配的内存块位于哪个内存堆上,就像是操作一个内存堆一样。

在这里插入图片描述
内存堆的初始化函数是在系统启动的时候自动初始化的,而不是我们用户在main函数中再初始化。
在这里插入图片描述
我们可以使用RT free进行内存块的释放。同时在内存块的分配和内存块的释放时还设置了相应的钩子函数。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2110906.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux详解】命令行参数|环境变量

目录 一、命令行参数 二、环境变量 1.环境变量的基本概念 2.查看环境变量的方法 3.环境变量相关命令 4.环境变量的组织方式以及获取环境变量的三种方法 环境变量具有全局属性 一、命令行参数 【示例1】main函数也是函数,main函数可以带参吗? 没…

Python教程(二十) : 十分钟入门【PyQt6】

文章目录 专栏列表环境准备1 安装 Python2 安装 PyQt6 PyQt6 中的模块使用模块创建一个窗体: PyQt6 常用的控件1. QPushButton(按钮)2. QLabel(标签)3. QLineEdit(文本输入框)4. QTextEdit&…

(4)SVG-path中的椭圆弧A(绝对)或a(相对)

1、概念 表示经过起始点(即上一条命令的结束点),到结束点之间画一段椭圆弧 2、7个参数 rx,ry,x-axis-rotation,large-arc-flag,sweep-flag,x,y (1)和(2&a…

FFMpeg环境搭建(WIN10)

0、前期准备 软件环境:Win10 qtcreator 软件准备:MSYS2 安装包、 FFmpeg源码 1、软件安装 通过MSYS2安装编译工具 1、打开MSYS2安装包,一路next即可 (注:如果需要更改路径可以自行更改) 2、安装完成…

虚拟现实辅助工程技术助力多学科协同评估

在当今高速发展的经济环境中,制造业面临着多重挑战,包括提高产品性能、压缩设计周期、实现轻量化设计和降低成本。为了有效应对这些挑战,多学科协同评估成为缩短研发周期和提升研制质量的关键手段。 传统的多学科评估面临着数据孤立与融合困难…

Android 系统源码项目加载预编好的so库

Android 系统源码项目加载预编好的so库 文章目录 Android 系统源码项目加载预编好的so库一、前言二、源码中加载so1、Android.mk加载so加载so的主要相关代码: 2、Android.bp加载so(1)Android.mk使用源码命令编译成Android.bp(2&am…

Java灰度发布

有没有在北京面试java的小伙伴,每家公司面试问的问题都不一样,昨天面试官问到了灰度发布,一脸懵,好像在哪儿听说过,毕竟我都没发布过,之前都是项目组长在干这些事儿,所以聊聊,了解一…

驾驭Autofac,ASP.NET WebApi实现依赖注入详细步骤总结

前言 嘿,小伙伴们,今天我们来一场 Autofac 的学习之旅吧! Autofac 是一个轻量级的依赖注入框架,专门为 .NET 应用程序量身定做,它就像是你代码中的 “魔法师”,用它来管理对象的生命周期,让你…

828华为云征文|华为云Flexus X实例docker部署最新gitlab社区版,搭建自己的私人代码仓库

828华为云征文|华为云Flexus X实例docker部署最新gitlab社区版,搭建自己的私人代码仓库 华为云最近正在举办828 B2B企业节,Flexus X实例的促销力度非常大,特别适合那些对算力性能有高要求的小伙伴。如果你有自建MySQL、Redis、Ng…

大数据采集迁移工具

Flume Sqoop kafka框架 MQ:消息队列 broker相当于服务器 消息队列

栈和队列(1)

空栈先移动栈顶再加数据,满栈先插入数据再移 栈的基本概念栈是一种后进先出(LIFO,Last In First Out)的数据结构。栈支持两种主要的操作:•压栈(Push):向栈中添加一个元素。•弹栈&…

Kubernetes v1.28.0安装详解

Kubernetes v1.28.0安装详解 一.环境初始化 要在所有节点执行命令进行配置 1、检查操作系统的版本 此部署环境为CentOS 7.9 [rootCentOS7 ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) [rootCentOS7 ~]#2、主机名解析 为了方便集群节点间的互相调…

活动系统开发之采用设计模式与非设计模式的区别-数据库设计及代码设计

1、数据库ER图 2、应用框架选用 PHP语言对应的thinkphp6.1应用框架 3、功能代码设计(后端) a、父类Base.php i:控制登录,只能登录后管理员才能操作; ii:控制按钮权限,管理员不仅要登录,且必须要有对应菜单…

报错处理:超过Uobject最大数量

处理方式 一、打包时项目中设置游戏中UObject的最大数量为100000000 二、打包后的配置文件中设置 打包路径: 一厅统管\Windows\YZ_YTTG\Saved\Config\Windows\Engine.ini文件下添加配置文件 [/Script/Engine.GarbageCollectionSettings] gc.MaxObjectsInEditor1000…

API 网关 OpenID Connect 实战:单点登录(SSO)如此简单

作者:戴靖泽,阿里云 API 网关研发,Higress 开源社区 Member 前言 随着企业的发展,所使用的系统数量逐渐增多,用户在使用不同系统时需要频繁登录,导致用户体验较差。单点登录(Single Sign-On&a…

2024最新!Facebook手机版和网页版改名教程!

Facebook作为全球最大的社交平台之一,允许用户自定义名字和昵称。在Facebook更新姓名可以帮助您更好的展现账号形象。本文将为您提供详细的步骤指导,帮助您在手机APP和网页版上轻松完成Facebook改名操作。 Facebook手机版改名 打开Facebook APP并登录账号…

区块链ARC如何能让节点能够大规模处理交易数据

​​发表时间:2024年8月7日 TAAL技术主管Michael Bckli表示,TAAL公司一直在对ARC进行测试,并准备在今年年底全面发布。因TAAL在区块链交易处理方面具备深厚的专业知识,BSV区块链委托TAAL进行ARC开源参考落地方案的开发。 ARC是一个…

魔珐科技受邀参与外滩大会:以3D数字人AIGC产品赋能大资管行业,重塑金融服务边界

在人工智能浪潮的推动下,金融行业正经历着前所未有的场景革命。2024年Inclusion外滩大会作为行业交流的盛会,汇聚了众多学者、专家及企业领袖,共同探讨AI技术在多领域的深度应用,特别是其在金融行业中的革新潜力。 在外滩大会上&…

在桌面商业分析应用程序中启用高级 Web UI

挑战 Mercur Business Control 应用程序在企业界,尤其是金融领域,拥有悠久的应用历史。它帮助企业处理、可视化和分析海量数据,从而做出明智的商业决策。 随着产品的不断演进和现代化,Mercur Solutions AB 为该应用创建了 Web 客…

使用RestTemplate获取国内大盘股票数据的基本信息并存入数据库中

目录 使用RestTemplate获取国内大盘股票数据的基本信息并存入数据库中 第一步:导入RestTemplate依赖,并配置RestTemplate让其加入到SpringIoC容器中 第二步:在yml文件定义股票的相关参数 第三步:向新浪网发送请求,获…