内存管理
2026/7/16大约 5 分钟内核组件内核内存管理堆内存内存池
内存管理
📚 本节导读
学习时长: 约 15 分钟
难度级别: ⭐⭐☆☆☆
前置知识: C 语言内存模型、基本数据结构和链表
内存管理是操作系统的核心功能之一。OneOS 提供了两套互补的内存管理机制:堆内存管理(动态分配)和内存池(固定大小块分配),能够满足从灵活的动态内存分配到确定性实时分配的各种场景需求。
🎯 学习目标
- 理解 OneOS 内存管理的两大分类:堆内存与内存池
- 掌握内存管理模块的配置依赖关系
- 了解内存算法选择:FIRSTFIT 与 BUDDY
- 熟悉内存信息结构体
os_meminfo_t - 建立整体知识框架,为后续深入各子模块做好准备
一、内存管理总览
1.1 两大核心机制
OneOS 的内存管理分为两大类别,分别适用于不同的使用场景:
┌──────────────────────────────────────────────────────────────────┐
│ OneOS 内存管理体系 │
│ │
│ ┌─────────────────────┐ ┌─────────────────────────────┐ │
│ │ 堆内存管理 │ │ 内存池 │ │
│ │ (Heap Memory) │ │ (Memory Pool) │ │
│ ├─────────────────────┤ ├─────────────────────────────┤ │
│ │ • 动态分配任意大小 │ │ • 固定大小块分配 │ │
│ │ • 灵活但非确定性 │ │ • 确定性分配时间 │ │
│ │ • 支持两种算法 │ │ • 无碎片问题 │ │
│ │ • 支持多堆实例 │ │ • 支持超时等待 │ │
│ │ • 支持内存追踪 │ │ • 支持溢出检测 │ │
│ └─────────────────────┘ └─────────────────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ FIRSTFIT 算法 │ │ 内存块 (Block) │ │
│ │ BUDDY 算法 │ │ 内存追踪 │ │
│ └─────────────────┘ └─────────────────┘ │
└──────────────────────────────────────────────────────────────────┘| 特性 | 堆内存(Heap) | 内存池(Memory Pool) |
|---|---|---|
| 分配粒度 | 任意大小(字节级) | 固定大小块 |
| 分配时间 | 非确定性 | 确定性(O(1)) |
| 碎片问题 | 存在外部/内部碎片 | 无碎片 |
| 适用场景 | 通用动态分配 | 高频、固定大小的对象分配 |
| 并发安全 | 通过信号量保护 | 通过自旋锁保护 |
| 超时等待 | 不支持 | 支持 |
1.2 配置依赖关系
/* 以下宏定义在 oneos_config.h 中配置 */
#define OS_USING_HEAP /* 启用堆内存管理 */
#define OS_USING_MEM_POOL /* 启用内存池管理 */
/* 堆内存依赖信号量,当启用 OS_USING_HEAP 时必须启用 OS_USING_SEMAPHORE */
/* 内存算法至少选择一种 */
#define OS_USING_ALG_FIRSTFIT /* 选择 FIRSTFIT 算法 */
#define OS_USING_ALG_BUDDY /* 选择 BUDDY 算法 */
/* 可选功能 */
#define OS_USING_MEMPOOL_CHECK_TAG /* 内存池溢出检测 */
#define OS_USING_MEM_TRACE /* 内存追踪 */依赖关系图:
OS_USING_HEAP
├── OS_USING_SEMAPHORE (必须)
├── OS_USING_ALG_FIRSTFIT (至少选一种)
└── OS_USING_ALG_BUDDY (至少选一种)
└── OS_USING_MEM_TRACE (可选)
OS_USING_MEM_POOL
└── OS_USING_MEMPOOL_CHECK_TAG (可选)二、内存信息结构体
2.1 os_meminfo_t
堆内存信息结构体定义在 kernel/include/os_memory.h 中:
struct os_meminfo
{
os_size_t mem_total; /* 堆内存总大小(字节) */
os_size_t mem_used; /* 当前已使用内存大小(字节) */
os_size_t mem_maxused; /* 历史最大使用内存大小(字节) */
};
typedef struct os_meminfo os_meminfo_t;字段说明:
| 字段 | 类型 | 含义 |
|---|---|---|
mem_total | os_size_t | 堆内存区域的总字节数 |
mem_used | os_size_t | 当前已分配且在使用的字节数 |
mem_maxused | os_size_t | 自初始化以来,内存使用的峰值(字节) |
使用示例:
os_meminfo_t info;
os_default_heap_info(&info);
os_kprintf("堆内存: 总计=%lu, 已用=%lu, 峰值=%lu\r\n",
info.mem_total, info.mem_used, info.mem_maxused);2.2 os_mpinfo_t
内存池信息结构体,用于获取内存池的统计信息:
struct os_mpinfo
{
os_size_t blk_size; /* 用户可用的单个内存块大小 */
os_size_t blk_total_num; /* 内存块总数量 */
os_size_t blk_free_num; /* 空闲内存块数量 */
};
typedef struct os_mpinfo os_mpinfo_t;三、存储算法选择
3.1 FIRSTFIT 算法
配置宏:OS_USING_ALG_FIRSTFIT
- 原理:从空闲链表头部开始扫描,找到第一个足够大的空闲块进行分配
- 优点:分配速度快,实现简单,内存利用率较高
- 缺点:长时间运行后可能产生外部碎片
- 适用场景:通用嵌入式应用,内存分配模式多样化
3.2 BUDDY 算法
配置宏:OS_USING_ALG_BUDDY
- 原理:基于 2 的幂次方大小进行内存管理,伙伴块可以合并
- 优点:减少外部碎片,合并速度快,适合频繁分配/释放
- 缺点:存在内部碎片(非 2 的幂次方大小的请求会被向上取整)
- 适用场景:需要频繁分配和释放内存、对碎片敏感的场景
注意:在
kernel/include/os_memory.h中,如果定义了OS_USING_HEAP,则必须至少选择一种算法(OS_USING_ALG_FIRSTFIT或OS_USING_ALG_BUDDY),否则会触发编译错误。
四、子章节导航
内存管理模块包含以下子章节,建议按顺序阅读:
| 章节 | 标题 | 说明 |
|---|---|---|
| 4.4.1 | 堆内存管理 | 默认堆与多堆 API 详解 |
| 4.4.2 | FIRSTFIT 算法 | 首次适应算法原理与实现 |
| 4.4.3 | BUDDY 算法 | 伙伴系统算法原理与实现 |
| 4.4.4 | 内存池 | 固定大小块内存池 API 详解 |
| 4.4.5 | 内存块 | 内存池基本单位详解 |
| 4.4.6 | 内存追踪 | 内存泄漏检测与完整性检查 |
📝 本节小结
- OneOS 内存管理分为堆内存和内存池两大类,分别适用于灵活分配和确定性分配场景
- 堆内存管理依赖
OS_USING_HEAP和OS_USING_SEMAPHORE宏,必须至少选择一种内存算法 - FIRSTFIT 算法简单高效,适合通用场景;BUDDY 算法减少碎片,适合频繁分配/释放场景
os_meminfo_t结构体提供堆内存的统计信息(总大小、已用、峰值)- 内存池通过
os_mpinfo_t结构体提供块大小、总数和空闲数统计