mem
mem
mem_map和mem_section的区别
在内核的内存管理中,mem_map
和 mem_section
是两种不同的机制,主要用于管理物理页(struct page
)的映射。它们的区别主要体现在内存模型、适用场景和实现方式上:
1. mem_map
- 定义:
mem_map
是一个全局的struct page
数组,直接映射所有物理内存的页帧。每个物理页面对应数组中的一个元素。 - 内存模型:
用于 平坦内存模型(Flat Memory Model) 或旧版本内核的连续内存管理。 - 特点:
- 简单直接:物理地址通过简单偏移计算即可转换为
mem_map
的索引。 - 连续内存假设:假设物理内存是连续的,适用于小内存或物理地址无空洞的场景。
- 内存浪费:若物理内存存在空洞(如 NUMA 或预留内存),
mem_map
仍会为空洞分配struct page
条目,导致空间浪费。
- 简单直接:物理地址通过简单偏移计算即可转换为
- 访问方式:
通过物理地址计算索引(例如:pfn = phys_addr >> PAGE_SHIFT
,page = &mem_map[pfn]
)。
2. mem_section
- 定义:
mem_section
是 稀疏内存模型(Sparse Memory Model) 的核心结构,将物理内存划分为多个段(Section),每个段管理自己的struct page
数组。 - 内存模型:
用于稀疏内存模型(CONFIG_SPARSEMEM
),支持非连续物理内存。 - 特点:
- 灵活高效:按需分配
struct page
数组,仅对实际存在的内存区域分配内存,避免空洞造成的浪费。 - 支持大内存:适用于物理内存分散或巨大的系统(如 TB 级内存)。
- 多级查找:物理地址需先定位到对应的
mem_section
,再在段内找到struct page
。
- 灵活高效:按需分配
- 访问方式:
- 根据物理地址计算段号(Section Number)。
- 通过全局
mem_section
数组找到对应的段。 - 在段内的
page
数组中定位具体页结构。
对比总结
特性 | mem_map | mem_section |
---|---|---|
内存模型 | 平坦内存模型(连续内存) | 稀疏内存模型(支持非连续内存) |
适用场景 | 小内存、物理地址连续 | 大内存、物理地址稀疏或非连续 |
数据结构 | 全局连续数组 | 分段管理,每段独立 page 数组 |
内存开销 | 可能浪费(为空洞分配条目) | 按需分配,节省内存 |
物理地址转换 | 直接偏移计算 | 多级查找(段号 + 段内偏移) |
内核配置选项 | 默认在非稀疏模型中启用 | CONFIG_SPARSEMEM |
演进背景
mem_map
的局限性:
随着内存容量增长和 NUMA 架构普及,物理内存常呈现非连续特性,导致mem_map
浪费严重。mem_section
的优势:
稀疏模型通过分段管理,动态分配struct page
内存,显著减少内存开销,成为现代内核(尤其是大内存系统)的默认选择。
代码示例
1 | // mem_map 的访问(平坦模型) |
结论
mem_map
适用于简单、连续的物理内存管理,但在现代系统中逐渐被淘汰。mem_section
通过稀疏模型解决了大内存和非连续内存的管理问题,是当前内核的主流方案。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Helloeuler!