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里的操作是首先从头哨兵开始找到该空闲块,判断前后是否也为空闲块,若是则合并,合并就是改大小字段和跳指针,然后链接进空闲块链表。

相关推荐
2601_966949652 小时前
如何根据研究的起止时间截取分钟级行情?Python 实战与 QuantDash 数据处理指南
开发语言·python·pandas·量化交易·1024程序员节·股票数据·quantdash
拓恒技术4 小时前
无人机巡检AI算法的工程化落地:从需求到交付的5个核心环节
人工智能·算法·无人机
晨曦中的暮雨4 小时前
限流算法——固定窗口、滑动窗口、漏桶、令牌桶
java·开发语言·算法
怕浪猫4 小时前
Claude Code vs Codex:Computer Use 实现原理深度拆解
算法·面试·github
喵了几个咪5 小时前
GoWind CMS 拆解:在 Go 里给 TipTap 搭一套 Yjs 协同后端
开发语言·后端·golang
程序员清风5 小时前
数据处理脚本工程化:日志、配置、命令行与测试
服务器·开发语言·数据库
文丑颜不良啊5 小时前
LeetCode876~900题目解析
java·leetcode
罗西的思考6 小时前
AI 时代的 “房谋杜断”:如何培养能力、品味与判断力
人工智能·算法·机器学习
aloha_7896 小时前
Java 基础、集合、异常与 JUnit 5 速查
java·junit·sqlserver
淡海水6 小时前
07-02-源码-.NET Core GC分配路径
算法·unity·c#·.netcore·gc·1024程序员节