FreeRTOS 内存管理

目录

一、内存管理相关知识

1、标准 C 库中的 malloc()和 free()也可以实现动态内存管理,但是如下原因限制了其使用:

2、内存碎片

3、内存泄露

(1)内存泄漏的常见原因:

(2)内存泄漏的解决办法包括:

二、内存分配5种方法

1、第一种方法(heap_1):

2、第二种方法(heap_2):

3、第三种方法(heap_3):

4、第四种方法(heap_4):

5、第五种方法(heap_5):

6、FreeRTOS 5种内存分配方法比较


一、内存管理相关知识

1、标准 C 库中的 malloc()和 free()也可以实现动态内存管理,但是如下原因限制了其使用:

(1)在小型的嵌入式系统中效率不高。

(2)会占用很多的代码空间。

(3)它们不是线程安全的。

(4)具有不确定性,每次执行的时间不同。

(5)会导致内存碎片。

(6)使链接器的配置变得复杂。

2、内存碎片

        采用分区式存储管理的系统,在储存分配过程中产生的、不能供用户作业使用的主存里的小分区称成“内存碎片”。

3、内存泄露

        内存泄露是指程序中已动态分配的堆内存由于某些原因未能被释放,导致系统内存浪费,进而可能引起程序运行速度减慢、系统性能下降,甚至系统崩溃等严重后果。

(1)内存泄漏的常见原因:

①编程错误。程序员可能忘记释放已申请的内存,或者没有及时释放内存。

②资源未关闭。在使用如任务句柄等资源时,如果没有正确关闭这些资源,可能导致它们占用的内存无法被释放,从而引起内存泄漏。

(2)内存泄漏的解决办法包括:

①及时释放不再使用的内存。程序员应养成及时释放不再使用的内存的习惯。

②正确处理异常。确保程序能够正常释放已经申请的内存空间。

③正确关闭资源。在使用资源时,应正确关闭这些资源,避免它们占用的内存无法被释放。

二、内存分配5种方法

1、第一种方法(heap_1):

(1)heap_1的分配方法

        heap_1 实现起来就是当需要 RAM 的时候就从一个大数组(内存堆)中分一小块出来,大数组(内存堆)的容量为configTOTAL_HEAP_SIZE。使用函数xPortGetFreeHeapSize()可以获取内存堆中剩余内存大小。

(2)heap_1 特性如下

①适用于那些一旦创建好任务、信号量和队列就再也不会删除的应用,实际上大多数的 FreeRTOS 应用都是这样的。

②具有可确定性(执行所花费的时间大多数都是一样的),而且不会导致内存碎片。

③代码实现和内存分配过程都非常简单,内存是从一个静态数组中分配到的,也就是适合于 那些不需要动态内存分配的应用。

2、第二种方法(heap_2):

(1)heap_2的分配方法

        heap_2提供了一个更好的分配算法,不像heap_1那样, heap_2提供了内存释放函数。heap_2不会把释放的内存块合并成一个大块,这样有一个缺点,随着你不断的申请内存,内存堆就会被分为很多个大小不一的内存(块),也就是会导致内存碎片!

(2)heap_2 的特性如下

①可以使用在那些可能会重复的删除任务、队列、信号量等的应用中,但应用中的任务、 队列、信号量和互斥信号量具有不可预料性(如所需的内存大小不能确定,每次所需的内 存都不相同,或者说大多数情况下所需的内存都是不同的)的话可能会导致内存碎片

②具有不可确定性,但是也远比标准C中的mallo()和free()效率高!

3、第三种方法(heap_3):

(1)heap_3的分配方法

这个分配方法是对标准C中的函数malloc()和free(的简单封装, FreeRTOS对这两个函数做了线程保护。

(2)heap_3 的特性如下

①需要编译器提供一个内存堆,编译器库要提供malloc(0)和free()函数。 比如使用STM32 的话可以通过修改启动文件中的Heap_Size来修改内存堆的大小。

②具有不确定性。

③可能会增加代码量。

注意,在 heap_3中 configTOTAL_HEAP_SIZE是没用的!

4、第四种方法(heap_4):

(1)heap_4的分配方法

        heap_4 提供了一个最优的匹配算法,不像 heap_2, heap_4 会将内存碎片合并成一个大的可用内存块,它提供了内存块合并算法。内存堆为ucHeap[],大小同样为configTOTAL_HEAP-SIZE。 可以通过函数 xPortGetFreeHeapSize()来获取剩余的内存大小。

(2)heap_4 特性如下

①可以用在那些需要重复创建和删除任务、队列、信号量和互斥信号量等的应用中。

②不会像heap_2那样产生严重的内存碎片,即使分配的内存大小是随机的。

③具有不确定性,但是远比C标准库中的malloc()和free()效率高。heap_4 非常适合于那 些需要直接调用函数 pvPortMalloc()和 vPortFree()来申请和释放内存的应用。注意, 我们移植FreeRTOS的时候就选择的heap_4!

5、第五种方法(heap_5):

(1)heap_5的分配方法

        heap_5 使用了和 heap_4 相同的合并算法,内存管理实现起来基本相同,但是 heap_5 允许内存堆跨越多个不连续的内存段

(2)heap_5 特性如下

①heap_5有多个内存堆,这些内存堆会被连接在一起,和空闲内存块链表类似,这个处理过 程由函数vPortDefineHeapRegions()完成。

②使用 heap_5 的时候在一开始就应该先调用函数 vPortDefineHeapRegions()完成内存堆 的初始化!然后才能创建任务、信号量等。

③heap_5 的内存申请和释放函数和 heap_4基本一样。

6、FreeRTOS 5种内存分配方法比较

(1)heap_1最简单,但是只能申请内存,不能释放。

(2)heap_2提供了内存释放函数,用户代码也可以直接调用函数pvPortMalloc()和 vPortFree()来申请和释放内存,但是 heap_2 会导致内存碎片的产生! 

(3)heap_3 是对标准 C 库中的函数malloc()和free()的简单封装,并且提供了线程保护。

(4)heap_4相对与heap_2提供了内存合并功能,可以降低内存碎片的产生,我们移植FreeRTOS 的时候就选择了heap_4。

(5)heap_5基本上和heap_4 一样,只是heap_5支持内存堆使用不连续的内存块。

  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值