Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Kernel
RT-Thread--内核学习memheap(七)
发布于 2018-10-05 16:35:20 浏览:2050
订阅该版
本帖最后由 yushigengyu 于 2018-10-12 09:58 编辑 继续来看RTT内存分配相关的算法,RTT文档中已经说明了,RTT的内存分配管理算法总共有三种,第一种在上一篇已经看过了,这篇来看看这第二种算法。 这种算法是最常见也时比较简单的内存分配算法。 这个算法中,内存池是由一个个小的内存控制块组成。这里贴一张官方的资料图: ![](https://pic2.zhimg.com/80/v2-3fa2ed613da64533543d884fcd9e7eec_hd.jpg) [attach]6466[/attach] 每个**内存控制块(不管是已分配的内存块还是空闲的内存块)都包含一个数据头**,其中包括: magic – 变数(或称为幻数),它会被初始化成0x1ea0(即英文单词heap),用于标记这个内存块是一个内存管理用的内存数据块,magic变数不仅仅用于标识这个数据块是一个内存管理用的内存数据块,实质也是一个内存保护字:如果这个区域被改写,那么也就意味着这块内存块被非法改写(正常情况下只有内存管理器才会去碰这块内存) used - 指示出当前内存控制块是否已经分配。 **内存控制块通过两个链表结构相连(官方的图只有一个),一个链表将所有内存控制块都连接起来,另一个链表将所有空闲的内存控制块连接起来**。 在内存分配控制器初始化的时候,它包含2个内存控制块,一个最大的内存控制块,它包含了所有可以使用的内存,另一个内存控制块作为内存控制块列表中的结尾内存控制块,标记出整个内存池的结尾。[attach]6467[/attach] 初始化时的整个内存池接下来再说下内存分配的流程: 当有线程申请该内存池的内存的时候。假设申请的内存大小为size。 首先判断size是否大于available_size, [list=1] [*]若大于,直接返回分配失败。 [*]若小于或等于,依次查找空闲内存控制块列表,并比较其与内存控制块内包含可使用内存的大小。这里有**可以考量的小地方**。每个内存控制块所包含的可使用内存大小有**两种储存方式**,一种是**直接存储在内存控制块**中,另外一种就是内存控制块链表查找到下一个控制块的首地址,然后**计算得出可用内存大小**。前一种可以减少一次计算加快分配速度,后一种可以节约控制块的额外体积。RTT中采用的是第二种方案。 [*]若找到了对应的控制块。判断是否需要拆分内存控制块。拆分的意思是,该内存控制块对于申请的内存总量来说太大了(例如,内存块中有1K内存,申请了200个字节),就会将这个内存块拆分成两块(200+800)。 [*]找不到对应的控制块说明虽然总空间够用,但是大的内存被占用的内存分割了,这也就是传说中的内存碎片了。这种情况继续加重的话有可能导致最终无法分配大的内存。这也是这种内存分配算法的固有问题。 [/list]这里放一张分配过一次内存后的内存池结构。[attach]6468[/attach] 说完分配再说释放: 释放内存其实就是把内存控制块标志位的used标志清空,然后把该控制块重新加入空闲内存控制块列表。 其中有个需要注意的地方,前面已经说过如果所有内存块都拆分成小的内存块之后,有可能即使有足够的内存空闲,却也无法分配的情况。这种情况有两种,可以分别称为假内存碎片和真雷村碎片,如下。 [attach]6469[/attach] 假内存碎片 这种情况下,明显块3和块2是可以合并的。在RTT中,当释放内存的时候,会自动检测内存块的两边,如果有可以合并的内存块,就会在释放的时候直接完成合并的任务。 另一种是无法合并的情况: [attach]6470[/attach] 可以想象,随着内存的分配->释放->分配->释放...循环,最终可能会把一整个内存池分割成一个个这样的小内存块,此后就没法分配大块的内存。一般嵌入式设备可以通过定期重启解决这个问题。 关于RTT的memheap的内存分配算法就分析到这里。RTT还有一个内存分配算法,就留到下一篇来看了。
查看更多
1
个回答
默认排序
按发布时间排序
whj467467222
认证专家
2018-10-07
开源,分享,交流,共同进步
赞,楼主文采太好了,整理的很到位。
撰写答案
登录
注册新账号
关注者
0
被浏览
2.1k
关于作者
yushigengyu
这家伙很懒,什么也没写!
提问
15
回答
25
被采纳
0
关注TA
发私信
相关问题
1
请教cpu使用率分析
2
选择FreeRTOS, 还是RT-Thread。
3
thread heap stack overflow ?
4
rtt消息队列delay问题
5
释放被删除线程的内存地方在哪里啊
6
请教:各线程结束后,释放其中的内存的连续性问题
7
STM32F103中断关于信号量、邮箱问题
8
RTT中的线程栈大小如何控制
9
关于线程由执行态变为挂起态的代码实现,,,
10
rt_malloc(rt_size_t size)内存分配函数最小分配尺寸问题
推荐文章
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组件
最新文章
1
在RT-Thread Studio中构建前执行python命令
2
研究一了一段时间RTT,直接标准版上手太难,想用nano,但又舍不得组件
3
CherryUSB开发笔记(一):FSDEV USB IP核的 HID Remote WakeUp (USB HID 远程唤醒) 2025-01-18 V1.1
4
RT-thread 缩写字典
5
RT Thread 源码分析笔记 :线程和调度器
热门标签
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
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
PWM
cubemx
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
813
个答案
177
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
149
次被采纳
本月文章贡献
聚散无由
2
篇文章
14
次点赞
catcatbing
2
篇文章
4
次点赞
Wade
2
篇文章
2
次点赞
Ghost_Girls
1
篇文章
4
次点赞
xiaorui
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部