目录
1、标准 C 库中的 malloc()和 free()也可以实现动态内存管理,但是如下原因限制了其使用:
(1)在小型的嵌入式系统中效率不高。
(2)会占用很多的代码空间。
(3)它们不是线程安全的。
(4)具有不确定性,每次执行的时间不同。
(5)会导致内存碎片。
(6)使链接器的配置变得复杂。
采用分区式存储管理的系统,在储存分配过程中产生的、不能供用户作业使用的主存里的小分区称成“内存碎片”。
内存泄露是指程序中已动态分配的堆内存由于某些原因未能被释放,导致系统内存浪费,进而可能引起程序运行速度减慢、系统性能下降,甚至系统崩溃等严重后果。
①编程错误。程序员可能忘记释放已申请的内存,或者没有及时释放内存。
②资源未关闭。在使用如任务句柄等资源时,如果没有正确关闭这些资源,可能导致它们占用的内存无法被释放,从而引起内存泄漏。
①及时释放不再使用的内存。程序员应养成及时释放不再使用的内存的习惯。
②正确处理异常。确保程序能够正常释放已经申请的内存空间。
③正确关闭资源。在使用资源时,应正确关闭这些资源,避免它们占用的内存无法被释放。
(1)heap_1的分配方法
heap_1 实现起来就是当需要 RAM 的时候就从一个大数组(内存堆)中分一小块出来,大数组(内存堆)的容量为configTOTAL_HEAP_SIZE。使用函数xPortGetFreeHeapSize()可以获取内存堆中剩余内存大小。
(2)heap_1 特性如下
①适用于那些一旦创建好任务、信号量和队列就再也不会删除的应用,实际上大多数的 FreeRTOS 应用都是这样的。
②具有可确定性(执行所花费的时间大多数都是一样的),而且不会导致内存碎片。
③代码实现和内存分配过程都非常简单,内存是从一个静态数组中分配到的,也就是适合于 那些不需要动态内存分配的应用。
(1)heap_2的分配方法
heap_2提供了一个更好的分配算法,不像heap_1那样, heap_2提供了内存释放函数。heap_2不会把释放的内存块合并成一个大块,这样有一个缺点,随着你不断的申请内存,内存堆就会被分为很多个大小不一的内存(块),也就是会导致内存碎片!
(2)heap_2 的特性如下
①可以使用在那些可能会重复的删除任务、队列、信号量等的应用中,但应用中的任务、 队列、信号量和互斥信号量具有不可预料性(如所需的内存大小不能确定,每次所需的内 存都不相同,或者说大多数情况下所需的内存都是不同的)的话可能会导致内存碎片。
②具有不可确定性,但是也远比标准C中的mallo()和free()效率高!
(1)heap_3的分配方法
这个分配方法是对标准C中的函数malloc()和free(的简单封装, FreeRTOS对这两个函数做了线程保护。
(2)heap_3 的特性如下
①需要编译器提供一个内存堆,编译器库要提供malloc(0)和free()函数。 比如使用STM32 的话可以通过修改启动文件中的Heap_Size来修改内存堆的大小。
②具有不确定性。
③可能会增加代码量。
注意,在 heap_3中 configTOTAL_HEAP_SIZE是没用的!
(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!
(1)heap_5的分配方法
heap_5 使用了和 heap_4 相同的合并算法,内存管理实现起来基本相同,但是 heap_5 允许内存堆跨越多个不连续的内存段。
(2)heap_5 特性如下
①heap_5有多个内存堆,这些内存堆会被连接在一起,和空闲内存块链表类似,这个处理过 程由函数vPortDefineHeapRegions()完成。
②使用 heap_5 的时候在一开始就应该先调用函数 vPortDefineHeapRegions()完成内存堆 的初始化!然后才能创建任务、信号量等。
③heap_5 的内存申请和释放函数和 heap_4基本一样。
(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支持内存堆使用不连续的内存块。