当前位置: 首页 > news >正文

【计算机基础】-49-Slab与Memory Pool内存空间来自哪里?初始化过程?申请和释放方法?代码示例?

在 RT-Thread 中,Slab AllocatorMemory Pool(rt_mp_t是两种独立的内存管理机制,它们的内存来源、初始化方式、申请/释放方法完全不同。下面从这四个方面详细对比,并附完整代码示例。


一、内存来源

机制内存来源
Slab Allocator来自系统堆(heap)<br>(即rt_system_heap_init()初始化的区域)
Memory Pool可来自:<br>1.系统堆(heap)(动态创建)<br>2.静态数组(静态创建,推荐用于 ISR)

关键区别

  • Slab只能从 heap 分配;
  • Memory Pool可选 heap 或静态内存。

二、初始化过程

1.Slab Allocator 初始化

  • 自动初始化:在rtthread_startup()中调用;
  • 前提:启用RT_USING_SLAB
  • 过程
    • 为每种内核对象(如 TCB、mutex)创建一个 slab cache;
    • cache 初始为空,首次分配时才从 heap 申请 slab。
// rtconfig.h #define RT_USING_SLAB // 系统启动时自动调用(用户无需干预) void rt_system_slab_init(void) { // 为 TCB 创建 cache rt_thread_slab = rt_slab_create("thread", sizeof(struct rt_thread), ...); // 为 semaphore 创建 cache... }

2.Memory Pool 初始化

  • 手动初始化:由用户调用 API 创建;
  • 两种方式
(1) 动态创建(从 heap 分配):rt_mp_create
rt_mp_t mp = rt_mp_create("mp", 64, 10); // 10 个 64 字节块
(2) 静态创建(使用静态数组):rt_mp_create_static
static uint8_t mp_buffer[64 * 10]; rt_mp_t mp = rt_mp_create_static("mp", 64, 10, mp_buffer);

推荐静态创建避免 heap 碎片,且 ISR 中更安全。


三、申请与释放方法

机制申请释放ISR 安全
Slab内核自动调用<br>(如rt_thread_create()内核自动调用<br>(如rt_thread_delete()⚠️ 间接支持
Memory Poolrt_mp_alloc(mp, timeout)rt_mp_free(block)✅ 直接支持

重要

  • 用户不能直接调用 Slab 的 alloc/free
  • Memory Pool 提供完整用户 API。

四、完整代码示例

场景:同时使用 Slab(线程) + Memory Pool(ISR 数据包)

#include <rtthread.h> /* ===== 1. Memory Pool 静态创建(推荐) ===== */ #define POOL_SIZE 10 #define BLOCK_SIZE 64 static uint8_t mp_buffer[BLOCK_SIZE * POOL_SIZE]; static rt_mp_t packet_pool = RT_NULL; /* ===== 2. 初始化函数 ===== */ int memory_init(void) { /* 创建静态 Memory Pool */ packet_pool = rt_mp_create_static("pkt_pool", BLOCK_SIZE, POOL_SIZE, mp_buffer); if (packet_pool == RT_NULL) { rt_kprintf("Failed to create memory pool\n"); return -1; } rt_kprintf("Memory pool created: %d blocks of %d bytes\n", POOL_SIZE, BLOCK_SIZE); return 0; } INIT_APP_EXPORT(memory_init); /* ===== 3. ISR 使用 Memory Pool ===== */ extern rt_mailbox_t data_mb; // 假设已创建邮箱 void uart_rx_isr(void) { // 从 Memory Pool 分配(非阻塞) void *buf = rt_mp_alloc(packet_pool, RT_WAITING_NO); if (buf) { // 模拟读取数据 *((int*)buf) = rt_tick_get(); // 存入时间戳 // 发送给线程处理 rt_mb_send(data_mb, (rt_ubase_t)buf); } // 若失败,丢包(无 heap 依赖,安全) } /* ===== 4. 线程处理并释放 ===== */ void data_process_thread(void *param) { rt_ubase_t msg; while (1) { if (rt_mb_recv(data_mb, &msg, RT_WAITING_FOREVER) == RT_EOK) { void *buf = (void *)msg; rt_kprintf("Received: tick=%d\n", *((int*)buf)); rt_mp_free(buf); // 归还到 Memory Pool } } } /* ===== 5. Slab 自动用于线程创建 ===== */ void create_worker_threads(void) { // 这些 TCB 由 Slab 从 heap 分配(零碎片) for (int i = 0; i < 3; i++) { char name[8]; rt_sprintf(name, "worker%d", i); rt_thread_t t = rt_thread_create(name, data_process_thread, RT_NULL, 512, 20, 10); rt_thread_startup(t); } } MSH_CMD_EXPORT(create_worker_threads, create workers);

五、内存布局示意

+---------------------------+ | System Heap (from linker) | ← rt_system_heap_init() | | | +-----------------------+ | | | Slab Cache (TCB) | | ← Slab 从 heap 切出 | | [TCB][TCB][TCB]... | | | +-----------------------+ | | | | (其他 heap 用户数据...) | +---------------------------+ +---------------------------+ | Static Memory (BSS) | | | | +-----------------------+ | | | mp_buffer[64*10] | | ← Memory Pool 静态数组 | +-----------------------+ | +---------------------------+

💡 如果 Memory Pool 动态创建,则其控制块和内存也来自 heap。


六、关键注意事项

项目SlabMemory Pool
是否需要用户管理❌ 否(内核自动)✅ 是
能否在 ISR 使用❌ 不能直接使用✅ 能(RT_WAITING_NO
内存碎片无(固定大小)无(固定大小)
适用对象内核对象(TCB等)用户数据(包、帧等)

✅ 总结

维度Slab AllocatorMemory Pool
内存来源系统堆(heap)heap 或静态数组
初始化系统自动用户手动(rt_mp_create
申请/释放内核自动(通过对象 API)用户显式(rt_mp_alloc/free
典型用途线程、信号量等内核对象ISR 数据包、固定帧缓冲区

🔑最佳实践

  • 内核对象 → 依赖 Slab(无需干预)
  • 用户实时数据 → 用静态 Memory Pool

两者共存无冲突,是构建高性能 RTOS 应用的黄金组合。

http://www.jsqmd.com/news/377504/

相关文章:

  • 支持OpenClaw智能体管理,新增企业微信、钉钉和飞书告警通知,1Panel v2.1.0版本发布
  • .Net Hangfire延长超时作业(默认30分钟),重复执行问题
  • 线上服务重启后,从nacos取不到配置了,怎么回事
  • 2026智能门窗市场剖析:这家公司表现如何?被动式窗/别墅装修/欧式门窗/豪宅设计/隔音门窗,智能门窗供应商哪家好 - 品牌推荐师
  • 1.5 AI技术栈三层架构:从应用到基础设施的完整拆解
  • 永辉超市购物卡兑换现金秘籍 - 团团收购物卡回收
  • 2.1 训练数据决定模型上限:多语言与领域数据详解
  • Linux_21:音频AI模块
  • 2026年无锡专业汽车零部件检测设备厂家直销价格及性价比分析 - mypinpai
  • 1.3 10大应用场景盘点:大模型落地实战全解析
  • 2026年最新版|番茄畅听下载与电脑版安装全流程详解 - PC修复电脑医生
  • 基于“链动2+1模式AI智能名片S2B2C商城小程序”的客户全生命周期价值最大化研究
  • 【计算机基础】-47-Buddy和Small Memory使用相同的API rt_malloc(), 他们能并存吗?如何区分?
  • 全网首测!MiniMax M2.5发布,跑OpenClaw实测真香
  • 10 个新颖的 Python 毕业设计题目
  • 【计算机基础】-48-Slab与Memory Pool可以共存吗?他们的API函数相同吗?代码示例
  • MIT_65840 Lab2 KV Server 与分布式锁
  • iPaaS从连接到智能:企业集成平台选型进入新阶段
  • 分期乐购物额度怎么提取?零基础新手也能轻松搞定! - 团团收购物卡回收
  • 2026年深圳古驰手表维修推荐评测:非官方维修点选择指南与全国服务网点排名 - 十大品牌推荐
  • 源码阅读:Android UI分发机制
  • 10 个新颖且有挑战性的 Python 编程题目
  • 2026年广东地区金蝙蝠工艺家具性价比分析,怎么选不吃亏 - 工业推荐榜
  • 【IEEE出版、往届会后4个月检索】第八届信息科学、电气与自动化工程国际学术会议(ISEAE 2026)
  • 2026年深圳古驰手表维修推荐榜单评测:非官方维修网点服务与售后中心选择指南 - 十大品牌推荐
  • uv pyseekdb:把 RAG 环境与检索落地成本降到最低
  • 语言、开发语言程序设计语言--SMP(软件制作平台)语言基础知识之六十一
  • 教你轻松处理永辉超市购物卡 - 团团收购物卡回收
  • 基于ID3算法的MATLAB销量预测实现
  • 从“防贼”到“信人”——管理的本质回归