1. 内存管理全景:Linux内存管理子系统概述、虚拟内存与物理内存、MMU与页表基础
1.1 Linux内存管理子系统全景
Linux内存管理子系统是内核中最复杂、最核心的模块之一,负责协调系统中所有内存资源的分配、回收与映射。它向上为进程提供独立的虚拟地址空间,向下管理物理内存页框,中间通过MMU与页表完成地址转换。
核心职责: 地址映射、内存分配/回收、页面换入换出、缺页异常处理、内存碎片整理、内存热插拔。
内存管理子系统的主要组件与层次关系如下表所示:
| 层次/组件 | 核心数据结构 | 主要功能 |
|---|---|---|
| 进程地址空间 | mm_struct, vm_area_struct |
管理进程虚拟内存布局(堆、栈、映射段) |
| 虚拟内存映射 | 页表(Page Table) | 虚拟地址 → 物理地址转换 |
| 物理内存管理 | page, zone, pglist_data |
物理页框分配与回收 |
| 分配器 | 伙伴系统(Buddy System) | 连续物理页框分配,抗外部碎片 |
| 小块内存分配 | SLUB/SLAB分配器 | 内核对象缓存,抗内部碎片 |
| 页面回收 | LRU链表, kswapd | 页面换出与内存压力调节 |
1.2 虚拟内存与物理内存
虚拟内存是Linux为每个进程提供的独立、连续的地址空间抽象,而物理内存是硬件实际可寻址的RAM。两者通过页表建立映射关系。
关键概念: 虚拟地址(VA)由CPU生成,经过MMU转换为物理地址(PA)。进程只能看到虚拟地址,无法直接访问物理地址。
虚拟内存的核心优势:
- 隔离性: 每个进程拥有独立的虚拟地址空间,互不干扰。
- 安全性: 用户态进程无法访问内核空间。
- 灵活性: 允许使用比物理内存更大的地址空间(通过换页)。
- 简化编程: 程序员无需关心物理内存碎片和布局。
虚拟地址空间布局(以x86-64为例):
| 区域 | 起始地址 | 说明 |
|---|---|---|
| 代码段(.text) | 0x400000 |
可执行指令 |
| 数据段(.data/.bss) | 代码段之后 | 全局变量、静态变量 |
| 堆(Heap) | 数据段之后 | 动态分配(brk/mmap) |
| 内存映射段 | 堆与栈之间 | 共享库、mmap文件 |
| 栈(Stack) | 高地址向下增长 | 局部变量、函数调用 |
| 内核空间 | 0xFFFF8000 00000000 |
内核代码与数据(用户态不可见) |
1.3 MMU与页表基础
内存管理单元(MMU)是CPU内部的硬件模块,负责将虚拟地址实时转换为物理地址。页表是存储在内存中的多级数据结构,MMU通过遍历页表完成地址转换。
性能关键: 每次内存访问都需要一次页表遍历(多级查表),TLB(Translation Lookaside Buffer)作为页表的硬件缓存,可以大幅加速地址转换。TLB miss会导致性能下降。
x86-64四级页表结构:
| 页表级别 | 缩写 | 索引位数 | 覆盖范围 |
|---|---|---|---|
| 页全局目录 | PGD | 9 bits | 512 个 PMD 条目 |
| 页上级目录 | PUD | 9 bits | 512 个 PMD 条目 |
| 页中间目录 | PMD | 9 bits | 512 个 PTE 条目 |
| 页表条目 | PTE | 9 bits | 512 个物理页框(4KB) |
地址转换过程(x86-64,4KB页):
- CPU发出48位虚拟地址
VA[47:0]。 - MMU从控制寄存器
CR3读取PGD基地址。 - 使用
VA[47:39]作为PGD索引,找到PUD表地址。 - 使用
VA[38:30]作为PUD索引,找到PMD表地址。 - 使用
VA[29:21]作为PMD索引,找到PTE表地址。 - 使用
VA[20:12]作为PTE索引,找到物理页框基地址。 - 物理地址 = 页框基地址 +
VA[11:0](页内偏移)。
1.4 页表条目(PTE)标志位
每个PTE不仅包含物理页框号(PFN),还包含一组标志位,用于控制页面的访问权限和状态。
| 标志位 | 含义 | 说明 |
|---|---|---|
P (Present) |
页面是否在物理内存中 | 0表示缺页,触发缺页异常 |
R/W |
读写权限 | 0只读,1可读写 |
U/S |
用户/超级用户权限 | 0仅内核可访问,1用户态也可访问 |
A (Accessed) |
页面是否被访问过 | 硬件自动置位,用于页面置换算法 |
D (Dirty) |
页面是否被写入过 | 硬件自动置位,用于回写判断 |
NX (No-Execute) |
禁止执行 | 防止代码段被篡改执行 |
实战要点: 缺页异常(Page Fault)是内存管理中最频繁的事件之一。当PTE的Present位为0时,MMU触发缺页异常,内核根据异常类型(有效/无效/保护错误)执行不同的处理流程,如分配物理页、从swap分区换入、写时复制(COW)等。
1.5 本章小结
本章建立了Linux内存管理子系统的全景视图,明确了三个核心概念:
- 虚拟内存 为进程提供独立、连续的地址空间抽象,通过页表映射到物理内存。
- 物理内存 是硬件RAM,由内核统一管理,通过伙伴系统和SLUB分配器分配。
- MMU与页表 是地址转换的硬件基础和软件数据结构,多级页表结构在灵活性和性能之间取得平衡。