FreeRTOS提供了几个内存管理的方案,其中一个实现较好的方式是heap4。本篇就来形象讲述heap4的工作原理。
本文暂时只用作自己对heap4的工作机制的总结和记录,有空了再修改成教程吧,所以,很多临时的图片就直接往上贴了
![](https://img-blog.csdnimg.cn/20181125184119910.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2p0ZDkwMDkwMDE=,size_16,color_FFFFFF,t_70)
基本原理:
ucHeap是一块由bss段分配的内存区域,heap4的核心内存管理特点是只监控空闲块(free block),不直接监控分配块。不管是空闲块还是分配块,其内存空间都由一个2-word的控制结构开头,第一个word是下一个空闲块的地址,第二个word用来标记内存大小。
空闲块由xStart开始,依次通过链表连接在一起组成free list。分配空间时,将会从头(xStart)开始找空间足够的空闲块。找到后,将空闲块原来的控制块进行修改,第一个word修改为0,表示该块已经不是空闲块。由于现在这个空闲块的一部分已经被分配,所以第二给我word将被修改为新分配的大小(注意,这里的新分配的大小不仅仅是malloc时候请求的size,而是要加上前面的控制块的大小并且进行对其处理。对于每一个内存控制块而言,其第二个word总是用于被描述其所管理的整个、也就是包含控制块自身的内存的大小),另外,由于该块已经被分配,将第二个word的最高位标记为1,用于分配标记(因此先前括号中我使用了“描述”这个词而不是“等于”)。那么从空闲块中分离出来剩下的那部分内存(如果还有多余的话)怎么办呢,答案是将这部分内存分离出来,成为一个新的空闲块,链接到原有的free list中(注意,这个链接过程最后得到的free list的链的方向一定是单向的)。然后将控制块偏移2个word的地址作为分配内存指针由返回值返回。
对于内存的释放,将申请得到的内存指针往前偏移2个word,然后根据释放后内存是否有可能连续的算法,尝试往前或者往后合并内存块,这个过程就这样带过,看源码的话基本上就能知道这个过程。
整个过程基本上就是这样,heap4的几个要点:
空闲块的第一个word指向下一个空闲块;
空闲块的第二个word等于这个空闲块的整个大小;
分配块的第一个word为NULL;
分配块的第一个word等于这个分配块的大小加上flag标记;
空闲块链表永远是单向链接;
分配内存时采用内存分裂算法,不断地从空闲块中申请内存;
释放内存时采用内存拼接算法,尝试拼接内存地址连续的空闲块;
cloud制作了一个在linux环境下分析内存的工具,用于从运行的系统中,将mcu全部内存dump出来,找出所有的分配块和空闲块。这个工具用于分析系统奔溃情况下FreeRTOS系统的内存管理是否出现异常,便于内存分析快速定位问题。地址如下:
https://github.com/442534820/fh4ct.git
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)