Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
堆_heap_动态内存管理
学习过程总结
RT-Thread学习笔记 --(9)RT-Thread内存管理学习过程总结
发布于 2021-01-07 09:02:07 浏览:1982
订阅该版
[tocm] 在单片机芯片上,如果不考虑出厂固化的ROM空间的话,通常开发者能接触到的存储空间主要分两种:掉电可保存数据的片内FLASH和掉电不可保存数据的片内RAM。 片内RAM(通常理解为内存)的访问速度比较快,可以按照变量地址随机访问,但断电后数据丢失。片内FLASH(通常理解为硬盘)所保存的内容比较固定,主要用来保存程序本身的数据内容,保存的内容断电不丢失。 对于单片机的片内RAM内存,主要有堆和栈之分,本章的内存管理,主要是基于堆内存管理进行开展的,在RT-Thread中,有两种堆内存管理方式:**动态内存堆管理和静态内存池管理**。 关于RT-Thread内存管理相关的内容,官方提供了比较丰富的文档作为参考,具体可以查看以下链接: [https://www.rt-thread.org/document/site/programming-manual/memory/memory/](https://www.rt-thread.org/document/site/programming-manual/memory/memory/) 本文尝试从以下几个方面总结一下RT-Thread内存管理的学习过程 ![1.png](https://oss-club.rt-thread.org/uploads/20210107/6afe4e822a98d29535a7b9eb440db5ac.png) ## **内存管理相关介绍** 在运行操作系统的单片机上面,代码和变量会占用一部分固定的内存开销,操作系统在初始化的时候,会去除掉这部分已经占用的内存,把剩下的闲置内存纳入到系统堆里面进行统一管理,不管是动态堆内存,还是静态内存池,都是使用这部分闲置空间的。 ![2.png](https://oss-club.rt-thread.org/uploads/20210107/132fa86ca043fad43522f8b0d73a4c88.png) 由于在实时操作系统里面对时间的要求十分严格,为了保证内存分配的时候不影响系统的实时性,就需要确保分配内存的时间是确定并可控的;并且在内存分配达到一定次数后,就不可避免地产生内存碎片;与此同时,嵌入式设备的内存资源相对有限,有些系统只有几十KB内存,而有些系统则有几十MB。 所以,为了解决以上内存分配可能出现的问题,需要使用一些内存管理算法来进行这些内存分配管理,RT-Thread提供了两种内存管理方式,分别是:**动态内存堆管理和静态内存池管理**。 ## **动态内存堆管理** 内存堆管理分配主要用于系统动态分配内存的场合,比如,我们使用动态方式创建某些内核对象(如消息队列,邮箱,信号量,等等)的时候,所使用到的内存空间就是动态内存堆。动态内存堆的意思是,要用多少,系统就分配多少给你,不用的时候,就要进行释放,还给系统再进行统一管理。 关于动态内存堆的管理,主要有三种算法:**小内存分配算法,slab算法,memheap算法**。关于这三种管理算法的实现原理介绍,RT-Thread官方已经给出了比较详细的解释,这里不再重复论述。 ![3.png](https://oss-club.rt-thread.org/uploads/20210107/f860669dbd193dd1c8be4b7666c9fe80.png) 需要注意的是,这三种内存管理算法,我们只能通过menuconfig来配置系统内核,选择其中一种内存管理方法,对于用户的应用程序接口而言,这三种算法是透明的,也就是说提供给用户的内存管理接口是相同的,只是算法的实现原理不同。 关于动态堆内存管理,操作系统提供了以下API接口函数,如下图所示。 ![4.png](https://oss-club.rt-thread.org/uploads/20210107/f82d03c4e0e0bdc918397689ec6a1d14.png) ## **静态内存池管理** 在使用动态内存堆管理系统内存的时候,这种方式非常灵活和方便,想用内存的时候就向系统申请分配,不用的时候就释放还给系统,但这种方式也存在一定的弊端。 主要是向系统申请内存的时候,都要遍历一次空闲内存的链表,查找可用的内存块,然后再分配给用户,而且这种方式不可避免地会产生内存碎片,所以这种内存管理方式的效率不是很高。这是一种“用时间换空间”的内存管理方式。 为了提高内存的分配效率,RT-Thread提供了静态内存池管理的方式。静态内存池就是系统把自身管理的内存预先划分为多个固定大小的内存块,当用户需要申请内存的时候,就从这些固定大小的内存块里面申请。 静态内存池管理的方式,还支持线程挂起操作,当系统没有内存块可用时,线程就会挂起等待,直到能申请到可用的内存块,这种特性可以用做线程间同步。 关于静态内存池的工作机制,如下图所示。 ![5.png](https://oss-club.rt-thread.org/uploads/20210107/e726d7273b5e0e0485bbf66abeeeed21.png) RT-Thread提供了以下API函数接口,用于静态内存池管理。 ![6.png](https://oss-club.rt-thread.org/uploads/20210107/43dd3d374c52173816a88c383b0f8060.png) ## **内存堆和内存池的应用示例** 内存管理相关的应用示例,主要是为了验证动态内存堆管理和静态内存池管理相关的API函数接口,这里包含两个示例,分别是内存堆管理示例和内存池管理示例。 示例源码下载链接: [https://github.com/embediot/rtthread_study_notes](https://github.com/embediot/rtthread_study_notes) [https://gitee.com/embediot/rtthread_study_notes](https://gitee.com/embediot/rtthread_study_notes) **内存堆管理示例**会创建一个动态的线程,这个线程会动态申请内存并释放,每次申请更大的内存,当申请不到的时候就结束。例程中分配内存成功并打印信息;当试图申请 65536 byte 即 64KB 内存时,由于开发板的单片机 RAM 总大小只有 64K,而可用 RAM 小于 64K,所以分配失败。 **内存池管理示例**会创建一个静态的内存池对象,2 个动态线程。一个线程会试图从内存池中获得内存块,另一个线程释放内存块内存块。总共初始化了 4096 /(80+4) = 48 个内存块。 1.线程 1 申请了 48 个内存块之后,此时内存块已经被用完,需要其他地方释放才能再次申请;但此时,线程 1 以一直等待的方式又申请了 1 个,由于无法分配,所以线程 1 挂起; 2.线程 2 开始执行释放内存的操作;当线程 2 释放一个内存块的时候,就有一个内存块空闲出来,唤醒线程 1 申请内存,申请成功后再申请,线程 1 又挂起,再循环一次②; 3.线程 2 继续释放剩余的内存块,释放完毕。 在memory_test.h头文件里面,通过打开相应的宏定义开关,重新编译工程源码,下载到开发板即可验证实验现象,如下图所示。 ![7.png](https://oss-club.rt-thread.org/uploads/20210107/2f8075041be38792f4d4a2a8f84c0253.png) ## **内存管理相关注意事项** 在使用RT-Thread内存管理相关接口的时候,为了确保系统稳定性,有以下注意事项: 1.由于系统为了保证内存在多线程的状态下能安全分配,引入了互斥操作,因此不能在中断服务程序里面分配或释放内存块,否则会引起当前线程被挂起。 2.在使用内存堆管理的时候,产生的内存碎片会在系统空闲线程运行的时候进行回收。 3.用户应用程序在申请内存分配的时候,建议判断是否申请成功,并对申请成功的内存空间进行初始化后再使用。 4.动态内存堆管理是一种“用时间换空间”的内存管理方式,这种方式可以节省一定的内存空间,但会损失一点效率。 5.静态内存池管理是一种“用空间换时间”的内存管理方式,这种方式相对来说比较高效,但会造成一定的空间浪费。 6.对于以KB为单位的单片机片内RAM内存,一般采用动态内存堆里面的小内存管理算法即可。 ![qrcode40.png](https://oss-club.rt-thread.org/uploads/20210107/44c54532c5d27ecb8d818f1e7e1b22cc.png)
1
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
embediot
这家伙很懒,什么也没写!
文章
11
回答
0
被采纳
0
关注TA
发私信
相关文章
1
rt_malloc 申请内存失败
2
webnet heap最大使用量。
3
调度锁会引起线程内存不足
4
RT-Thread内存和字符串相关函数与C语言自带的内存和字符串相关函数冲突问题
5
webnet 是否可以做全动态网页,使用内存池来加快速度
6
boatload跳转到app反复重启,难道你们编译器有问题?
7
怎么释放动态线程占用的内存
8
内存堆使用时产生不对齐
9
pandora开发板使用cjson,内存不足。
10
小内存管理中rt_realloc的实现问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
805
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部