heap_4内存管理

一、基础

1、静态大数组用于分配内存

cpp 复制代码
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];//编译期的静态数组,用于分配

2、块头链表

cpp 复制代码
typedef struct A_BLOCK_LINK
{
	struct A_BLOCK_LINK *pxNextFreeBlock;	/*<<下一块空闲内容*/
	size_t xBlockSize;						/*<<当前空闲块大小,最高位表示是否分配*/
} BlockLink_t;

3、头尾哨兵

cpp 复制代码
static BlockLink_t xStart;   /* 链表头(地址最小,xBlockSize=0) */
static BlockLink_t *pxEnd;   /* 链表尾(地址最大,标记"没有更多块了") */

头哨兵:作为查找起始

尾哨兵:作为查找结束

二、prvHeapInit

1、从堆内存起点进行八字节对齐

2、初始化头哨兵,指向对对齐后的起点,大小为0

cpp 复制代码
xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;  /* 链表第一项 = 对齐后的起点 */
xStart.xBlockSize = ( size_t ) 0;                    /* 哨兵自身大小为 0 */

3、初始化尾哨兵,从堆内存尾部往前8个字节再向下对齐

4、初始化唯一空闲块也就是第一个空闲块,大小为可用堆-尾哨兵开销,指向尾哨兵

初始化后的ucHeap布局,头哨兵不在这块内存,但指向第一个空闲内存块

复制代码
ucHeap 数组(3072B)内部:

┌─────────────┐ 0x20000100(数组首地址,可能未对齐)
│ 对齐损失     │ 0~7 字节(不可用,prvHeapInit 里扣掉了)
├─────────────┤ ← pucAlignedHeap(对齐后的堆起点)
│ 块头 BlockLink_t │ 8 字节
│   ├ pxNextFreeBlock → 指向 pxEnd     ← 这就是"指向尾哨兵"的字段
│   └ xBlockSize    → 整个块的大小(含块头)
├─────────────┤
│ 空闲内容区    │ ← 真正能 malloc 出去的字节,当前整块都是空闲的
│   (约 3056B) │
├─────────────┤ ← pxEnd 地址(= 起点 + 总大小 - 8,向下对齐)
│ pxEnd 哨兵   │ 8 字节(xBlockSize=0, pxNextFreeBlock=NULL)
├─────────────┤
│ 尾部余量     │ 0~7 字节(pxEnd 对齐后剩下的,不可用)
└─────────────┘ 0x20000100 + 3072(数组末尾)

三、void *pvPortMalloc( size_t xWantedSize )

首先暂停任务调度,第一次调用时若没有初始化则进行初始化,将申请大小加上8字节块头,若剩余总空间大于总需要空间,则从头哨兵开始找第一个符合大小的内存块,内存块大小包含8字节块头和申请的内存大小。然后记录块的返回地址,把这块地方从空闲链表里摘除,将后续剩余空间作为一个新的空闲块放入空闲块链表,更新统计值,恢复任务调度。返回地址。

四、void vPortFree( void *pv )

首先往前8个地址找到块头,校验是否可以释放,可以的话就清楚标志位(最高位),然后挂起调度器,把空闲块大小加进总空闲数,调用prvInsertBlockIntoFreeList将该块插回空闲链表,prvInsertBlockIntoFreeList里的操作是首先从头哨兵开始找到该空闲块,判断前后是否也为空闲块,若是则合并,合并就是改大小字段和跳指针,然后链接进空闲块链表。

相关推荐
余额瞒着我当琳1 小时前
红黑树的实现--红黑树的概念、规则、效率、结构、旋转、查找、验证
数据结构·c++·算法
疯狂的维修1 小时前
关于用C#写电机起保停控制
开发语言·c#
程序员南飞1 小时前
win系统安装minio
java·数据结构·算法
青少儿编程课堂1 小时前
AC自动机多模式串匹配精讲:校园关键词巡检实战解析
c++·python·算法·bfs·信息学竞赛
Escalating_xu1 小时前
【Python】使用库:标准库、第三方库、pip、项目实战与程序打包
java·python·pip
longlongzihan2 小时前
LeetCode 5. 最长回文子串:从暴力匹配到中心扩展的思维演进
c++·算法·leetcode
waoooqwe2 小时前
问卷样本真实吗
大数据·数据库·算法·数据分析
Wang's Blog2 小时前
Java框架 SpringCloud 快速入门: 过滤器链执行顺序
java·spring cloud
苦瓜打怪兽2 小时前
leetcode 热题100(11. 盛最多水的容器)
python·算法·leetcode