轻量级操作系统FreeRTOS的内存管理机制(三)

本文由嵌入式企鹅圈原创团队成员朱衡德(Hunter_Zhu)供稿。

轻量级操作系统FreeRTOS的内存管理机制(二)中讲到,heap2.c的内存管理机制会导致内存碎片的问题,系统运行久后会出现无法分配大块内存的情况,heap4.c中的管理机制提供了解决方法,它是在heap2.c的基础上添加了地址相邻空闲块间合并的功能,而heap5.c是对heap4.c的进一步扩展,它能够支持多块不连续分布的RAM空间作为堆使用,本篇将对heap4.c、heap5.c中的管理机制进行分析。

一、heap4.c

1.重要结构体

2.重要变量

xBlockAllocatedBit在堆初始化时被赋值为:

即最高位为1,在分配内存的时候xBlockSize将和置位变量xBlockAllocatedBit相与,使得xBlockSize最高位置位,表示改内存块属于应用程序;在回收内存时,通过xBlockSize &= ~xBlockAllocatedBit操作,将xBlockSize 最高位清零表示该内存空间未分配,xBlockSize 最高位可用于判断该内存当前是应用程序还是操作系统管理。

3.堆初始化

prvHeapInit(void)函数用于初始化堆空间,在第一次内存分配前需要被调用,主要完成了几个工作:

1)根据字节对齐划分有效的可分配空间;

2)初始化链表结构;

初始化后的链表结构和内存空间:

在heap4.c方案中,链表结点是按照空闲块地址由低到高排序的。上图中,xStart是表头结点,pEnd是表尾结点指针,链表的表尾结点在堆中进行分配。

4.内存分配机制

heap4.c内存分配策略:空闲块通过链表结构进行管理,当需要分配一块内存时,遍历链表,找到第一块够大的空闲块进行分配,从链表中移除出来,同时检查这块空间是否过大,如果过大就将空闲块进行切割,然后将剩下部分重新用BlockLink_t描述并插入到链表中。

和heap2.c有所不同的是,当找到了合适的空闲块后,BlockLink_t中的成员xBlockSize的最高位会置位为1,以表示该空间属于应用程序:

因此,请求分配的空间大小xWantedSize不能大到最高位为1。

5.内存回收

在内存回收过程中,vPortFree函数会读取pv所指空间的BlockLink_t结构体,首先判断成员xBlockSize最高位是否为1(即该空间原属于应用程序),如果满足才进行内存回收。

在heap4.c中最大的特点是在回收内存时添加了相邻空闲块的合并的算法,函数prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert )将空闲块插入链表中(由vPortFree()调用),和heap2.c对比,所不同的有两点:

1)heap4.c的链表是按照地址低到高排序的,heap2.c的链表是根据空闲块大小排序的;

2)在插入链表过程中,判断插入位置的前后结点的空闲块是否和回收的内存空间在地址上连续,如果是,就进行合并。

以下图例是一个合并的过程:

二、heap5.c

heap5.c是对heap4.c的进一步拓展,heap5.c能够支持多块不连续的RAM空间作为内存分配空间,内存分配策略和回收机制和heap4.c一样。

heap5.c中定义了一个重要结构体:

这个结构体描述用作堆空间的一块内存的信息,记录了该内存块的起始地址和大小。多块不连续的内存使用一个HeapRegion_t[]数组记录,并且约定数组以{NULL, 0}元素结尾,其作为vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions )函数的参数,进行堆初始化。

在FreeRTOS中的WIN32-MSVC示例是采用heap5.c的内存分配策略,HeapRegion_t[]示例如下:

经过初始化后的堆空间和链表结构如下图所示:

vPortDefineHeapRegions()函数将HeapRegion_t[]数组中不连续的RAM空间连接起来:通过在一块内存末尾存储一个BlockLink_t结构体,其pxNextBlock成员指向下一块内存中的第一块空闲块以建立起连接。

heap5.c较heap4.c而言主要增加了这部分功能,保留了heap4.c中的内存分配、内存回收的思想。

关注微信公众号:嵌入式企鹅圈,获得上百篇物联网原创技术分享!


时间: 2024-10-10 15:43:52

轻量级操作系统FreeRTOS的内存管理机制(三)的相关文章

轻量级操作系统FreeRTOS的内存管理机制(二)

本文由嵌入式企鹅圈原创团队成员朱衡德(Hunter_Zhu)供稿. 上一篇文章中介绍了FreeRTOS多种内存管理机制中最简单的一种:全局声明一个静态数组ucHeap,然后通过指针偏移记录空间的分配情况,在这种内存机制下无法对内存进行释放.同时也介绍了内存操作过程中字节对齐的细节,本篇文章将会对FreeRTOS源码中第二种内存管理机制heap2.c进行讲解,在heap2.c中同样使用一个全局静态数组ucHeap来表示内存,heap2.c内存管理机制较heap1.c而言增加了内存释放的功能,通过使

轻量级操作系统FreeRTOS的内存管理机制(一)

本文由嵌入式企鹅圈原创团队成员朱衡德(Hunter_Zhu) 近几年来,FreeRTOS在嵌入式操作系统排行榜中一直位居前列,作为开源的嵌入式操作系统之一,它支持许多不同架构的处理器以及多种编译工具链,具有轻量级.容易移植和使用的特点.本篇文章将会对FreeRTOS提供的几种内存分配策略进行介绍,FreeRTOS允许开发者根据自己的项目实际需要选择不同的内存分配策略或者自定义分配内存策略. 一.FreeRTOS内存分配源码 FreeRTOS在创建任务.队列.互斥量.信号量.软件定时以及事件组的时

操作系统 内存管理机制

参考和查阅了一下他人的资料,整理下 虚拟内存.物理内存.Swap分区.页面置换机制等基础知识 虚拟地址空间 与 物理地址空间的关系 虚拟地址由操作系统维护,由MMU可以进行转换,扩大了内存空间分页管理. 大多数使用虚拟存储器的系统都使用一种称为分页(paging)机制. 虚拟地址空间划分成称为页(page)的单位,而相应的物理地址空间也被进行划分,单位是页帧(frame),一个在磁盘,一个在内存,页和页桢的大小必须相同.在32位地址的机器,它的虚拟地址范围从0~0xFFFFFFFF(4G),而这

你必须了解的java内存管理机制(三)-垃圾标记

本文在个人技术博客不同步发布,详情可用力戳 亦可扫描屏幕右侧二维码关注个人公众号,公众号内有个人联系方式,等你来撩... 相关链接(注:文章讲解JVM以Hotspot虚拟机为例,jdk版本为1.8) 1. 你必须了解的java内存管理机制-运行时数据区 2. 你必须了解的java内存管理机制-内存分配 3. 你必须了解的java内存管理机制-垃圾标记 前言 前面花了两篇文章对JVM的内存管理机制做了较多的介绍,通过第一篇文章先了解了JVM的运行时数据区,然后在第二篇文章中通过一个创建对象的实例介

c+内存管理机制

内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的 检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存泄漏几乎在每个C++程序中都会发生,因此要想成为C++高手,内存管理一关是必须要过 的,除非放弃C++,转到Java或者.NET,他们的内存管理基本是自动的,当然你也放弃了自由和对内存的支配权,还放弃了C++超绝的性能.本期专题 将从内存管理.内存泄漏.内存回收这三个方面来探讨C++内存管理问题.

Linux内存管理机制

一.首先大概了解一下计算机CPU.Cache.内存.硬盘之间的关系及区别. 1.  CPU也称为中央处理器(CPU,Central Processing Unit)是一块超大规模的集成电路, 是一台计算机的运算核心(Core)和控制核心( Control Unit).它的功能主要是解释计算机指令以及处理计算机软件中的数据.中央处理器主要由三核心部件组成,运算器.控制器和总线(BUS),运算器又主要由算术逻辑单元(ALU)和寄存器(RS)组成. 2.Cache即高速缓冲存储器,是位于CPU与主内存

垃圾回收GC:.Net自动内存管理 上(三)终结器

垃圾回收GC:.Net自动内存管理 上(三)终结器 垃圾回收GC:.Net自动内存管理 上(一)内存分配 垃圾回收GC:.Net自动内存管理 上(二)内存算法 垃圾回收GC:.Net自动内存管理 上(三)终结器 前言 .Net下的GC完全解决了开发者跟踪内存使用以及控制释放内存的窘态.然而,你或午想要理解GC是怎么工作的.此系列文章中将会解释内存资源是怎么被合理分配及管理的,并包含非常详细的内在算法描述.同时,还将讨论GC的内存清理流程及什么时清理,怎么样强制清理. 终结器 GC提供了另外一个能

32位机内存管理机制(上)

一直有看linux内核的冲动,内核有些部分是汇编编写的,无奈汇编不大懂,所以利用五一三天假期大概走了一边8086CPU架构的汇编,8086CPU还是16位的,我们现在都进入64位时代了,这两者之间有很大的区别,但是看看16位的CPU汇编还是很重要的,这有助于理解32位的80386CPU.这篇文章来分析下80386的内存管理的一些基础知识,包括实模式.保护模式和内存寻址等等. 1.实模式 处理器被复位或者加电的时候以实模式启动.这时候处理器中各寄存器以实模式的初始化值工作. 80386处理器在实模

[转载] python的内存管理机制

本文为转载,原作为http://www.cnblogs.com/CBDoctor/p/3781078.html,请大家支持原作者 先从较浅的层面来说,Python的内存管理机制可以从三个方面来讲 (1)垃圾回收 (2)引用计数 (3)内存池机制 一.垃圾回收: python不像C++,Java等语言一样,他们可以不用事先声明变量类型而直接对变量进行赋值.对Python语言来讲,对象的类型和内存都是在运行时确定的.这也是为什么我们称Python语言为动态类型的原因(这里我们把动态类型可以简单的归结