• 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支持内存堆使用不连续的内存块。

  • 相关阅读:
    Unity --- 滑动条,滚动条和滚动视图
    HTML详细基础(三)表单控件
    打通Web安全思路:为什么我们需要同源策略?
    Unity物理系统(一)物理系统相关组件
    OJ---Z 字形变换
    MySQL表的约束
    通过Selenium批量填写问卷
    json转换
    【STM32G431RBTx】备战蓝桥杯嵌入式汇总
    JUC并发编程——读写锁(基于狂神说的学习笔记)
  • 原文地址:https://blog.csdn.net/Calmer_/article/details/136381355