本篇目标:讲清 RTOS 内存管理为什么“针对性强”——嵌入式上没有万能分配器,只有按场景选方案。
一、为什么不能直接用 malloc/free
标准
malloc/free 的问题:- 时间不确定:空闲块合并、链表遍历的耗时不可预测,破坏实时性;
- 碎片化:长期运行后内存碎成小块,大块申请失败;
- 开销大:每块内存的管理头(metadata)在 MCU 上很奢侈。
所以 RTOS 的内存管理是按场景定制的。
二、静态 vs 动态
- 静态分配:编译期定好,零运行时开销、零碎片、完全确定。缺点是灵活性差。任务栈、TCB 常用静态分配(
stp_thread_init传的就是用户提供的栈和 TCB 内存)。
- 动态分配:运行时按需申请,灵活但需要管理算法。
stp_rtos 的对象体系同时支持两者:
stp_object_init(静态)+ stp_object_allocate(动态,从内存堆分配)。三、动态分配算法
3.1 first-fit(首次适配)
从空闲链表头开始找,第一个够大的块就分。快,但碎片多。
3.2 best-fit(最佳适配)
找“最接近请求大小”的空闲块。碎片少,但查找慢。
3.3 内存池(mem pool)
把内存切成固定大小的块,用空闲链表管理。O(1) 分配/释放、零碎片,适合固定大小的对象(消息、控制块)。代价是块大小固定,用不满就浪费。
方案 | 分配时间 | 碎片 | 适用 |
静态 | O(1) | 无 | 栈、TCB |
first-fit | O(n) | 多 | 通用堆 |
best-fit | O(n) | 少 | 通用堆 |
内存池 | O(1) | 无(内部) | 固定大小对象 |
四、stp_rtos 的对象容器
stp_rtos 把“内存管理”和“对象管理”绑在一起:
stp_object_allocate 根据类型查到 object_size,从堆里分配一块,初始化后挂到对应链表。这样线程、信号量、定时器……所有内核对象都统一管理,调试时还能遍历链表打印所有对象(配合 shell 的 list 命令)。五、小结
- 嵌入式内存管理没有银弹,按“时间确定性 vs 灵活性 vs 碎片”权衡;
- 固定大小对象优先内存池,栈和 TCB 优先静态;
- stp_rtos 用对象容器统一管理内核对象的内存。
核心一句话:RTOS 内存管理的核心是“用确定性换灵活性”,按场景选算法。







