1. 嵌入式内存概述
1.1 嵌入式系统内存的独特挑战
嵌入式系统与通用计算机(如PC、服务器)在内存管理上存在本质差异。嵌入式环境通常面临资源受限、实时性要求高、功耗敏感三大核心约束。理解这些特点是后续优化CMA(连续内存分配器)和低内存适配的基础。
核心认知:嵌入式内存优化的目标不是“最大化吞吐量”,而是“在有限资源下保证确定性延迟与系统稳定性”。
1.2 嵌入式内存的典型特点
| 特点 | 描述 | 对优化的影响 |
|---|---|---|
| 容量受限 | 典型嵌入式设备内存从几十KB(MCU)到几GB(高端SoC)不等,远小于PC | 必须精细化管理,避免内存碎片和浪费 |
| 物理连续需求 | 许多外设(DMA、Camera、GPU)要求物理连续内存 | CMA机制应运而生,但低内存时易分配失败 |
| 实时性约束 | 内存分配延迟必须可预测,不能出现不可控的缺页或回收 | 需要预分配、内存池、原子分配路径 |
| 功耗敏感 | 内存访问功耗占系统总功耗的20%~40% | 优化内存布局可减少DRAM刷新和总线访问 |
| 多级异构 | 常同时包含SRAM(片内)、DRAM(片外)、NAND/NOR Flash | 需根据访问频率和延迟差异做分层分配 |
1.3 SRAM 与 DRAM 的核心区别
嵌入式系统中,SRAM 和 DRAM 是两种最主要的随机存取存储器。它们在速度、容量、功耗和用途上存在显著差异,直接影响内存分配策略。
| 对比维度 | SRAM | DRAM |
|---|---|---|
| 存储单元 | 6个晶体管(6T)构成锁存器 | 1个晶体管+1个电容(1T1C) |
| 数据保持 | 静态保持,无需刷新 | 电容电荷会泄漏,需周期性刷新(~64ms) |
| 访问速度 | 极快(1~5 ns),接近CPU频率 | 较快(10~50 ns),但存在行/列地址切换延迟 |
| 集成密度 | 低(晶体管多,面积大) | 高(单元面积小,适合大容量) |
| 功耗特性 | 静态功耗较高(漏电流大),动态功耗较低 | 静态功耗低(无持续电流),动态功耗高(刷新+访问) |
| 典型容量 | KB ~ 几十MB(片内集成) | MB ~ GB(片外独立芯片) |
| 嵌入式用途 | CPU Cache、TCM、中断向量表、实时栈 | 主内存、帧缓冲、媒体数据、大块堆 |
实战提示:在低内存嵌入式系统中,SRAM 是“黄金资源”,通常用于存放实时性要求最高的代码和数据(如中断处理、OS调度器)。DRAM 虽然容量大,但访问延迟和刷新开销不可忽视,优化时应尽量减少不必要的DRAM访问。
1.4 嵌入式内存瓶颈分析
在嵌入式Linux或RTOS环境中,内存瓶颈通常表现为以下四种类型。识别瓶颈类型是选择优化策略的前提。
1.4.1 容量瓶颈
最直观的瓶颈。当系统物理内存不足以满足所有进程和内核的需求时,Linux内核会启动OOM Killer或触发内存回收。在嵌入式设备中,这通常表现为:
- 系统响应变慢,甚至完全无响应(hang住)。
- 关键服务进程被意外杀死。
- CMA分配请求因无法迁移页面而失败。
1.4.2 碎片瓶颈
嵌入式系统长时间运行后,内存碎片化是导致大块连续分配失败的主要原因。碎片分为两类:
- 外部碎片:空闲内存总量足够,但没有一块连续的物理地址空间满足分配请求。CMA机制正是为了解决此问题而设计,但在低内存时仍可能失败。
- 内部碎片:分配的内存块大于实际需求,造成浪费。例如使用kmalloc分配53字节时,SLAB分配器可能返回64字节的块。
避坑指南:不要认为“总内存够用”就等于“分配不会失败”。在嵌入式系统中,物理连续性往往比总容量更稀缺。CMA分配失败是低内存适配中最常见的“隐形杀手”。
1.4.3 延迟瓶颈
内存分配和访问的延迟直接影响系统的实时性。典型场景包括:
- 分配路径延迟:在中断上下文或软中断中调用
kmalloc(GFP_ATOMIC),如果内存不足导致进入慢速路径,可能引入不可预测的延迟。 - 缺页异常延迟:首次访问mmap映射的内存时,触发缺页中断,若此时需要从Flash或swap读入数据,延迟可达毫秒级。
- TLB缺失延迟:对于大页表(如4K页),TLB缺失频繁,增加地址转换开销。
1.4.4 带宽瓶颈
DRAM的带宽是共享资源。当多个主设备(CPU、GPU、Camera、Display)同时访问DRAM时,总线竞争会导致带宽下降。在嵌入式多媒体设备中,带宽瓶颈常表现为:
- 视频解码丢帧或花屏。
- GPU渲染帧率不稳定。
- DMA传输超时或数据损坏。
1.5 嵌入式内存优化的核心思路
基于上述瓶颈分析,嵌入式内存优化的总体策略可以归纳为以下四点:
| 优化方向 | 核心方法 | 对应瓶颈 |
|---|---|---|
| 减少浪费 | 使用内存池、SLAB/SLUB调优、裁剪内核配置 | 容量瓶颈、碎片瓶颈 |
| 保证连续 | CMA配置与调优、大页(HugeTLB)、预留内存(reserved-memory) | 碎片瓶颈 |
| 降低延迟 | 预分配、原子分配路径优化、Cache锁定、TCM使用 | 延迟瓶颈 |
| 提升带宽 | 多通道DRAM配置、DMA引擎卸载、内存访问对齐优化 | 带宽瓶颈 |