1. 内存管理概述:物理内存与虚拟内存的概念、MMU的作用、Linux内存管理子系统架构
1.1 物理内存与虚拟内存
物理内存(Physical Memory)是计算机系统中实际存在的硬件内存,通常由DRAM芯片组成,通过内存总线与CPU连接。每个物理内存单元都有一个唯一的物理地址(Physical Address, PA),CPU可以直接通过物理地址访问对应的存储单元。
虚拟内存(Virtual Memory)是一种内存管理技术,它为每个进程提供一个独立的、连续的、从0开始的地址空间(虚拟地址空间)。进程实际使用的虚拟地址(Virtual Address, VA)需要经过地址转换才能映射到真实的物理地址。
| 特性 | 物理内存 | 虚拟内存 |
|---|---|---|
| 本质 | 硬件DRAM芯片,真实存在 | 操作系统抽象出来的逻辑概念 |
| 地址空间 | 受硬件容量限制,通常较小 | 理论上可达2^64(x86-64),极大 |
| 连续性 | 物理上可能不连续(碎片化) | 对进程呈现连续的线性空间 |
| 隔离性 | 所有进程共享,无保护 | 进程间相互隔离,互不干扰 |
| 管理粒度 | 页框(Page Frame),通常4KB | 页(Page),与物理页框大小对应 |
核心观点:虚拟内存是现代操作系统实现进程隔离、内存保护和高效利用物理内存的基石。没有虚拟内存,一个进程的错误地址访问可以直接破坏其他进程甚至内核的数据。
1.2 MMU的作用
MMU(Memory Management Unit,内存管理单元)是CPU内部的一个硬件模块,负责将虚拟地址转换为物理地址。它是虚拟内存机制得以实现的硬件基础。
MMU的核心工作流程如下:
- 地址接收:CPU执行指令时,发出的地址是虚拟地址(VA)。
- 页表查找:MMU根据虚拟地址的高位部分(页号)查找当前进程的页表(Page Table),找到对应的页表项(PTE)。
- 权限检查:MMU检查PTE中的权限位(读/写/执行)和存在位(Present),判断访问是否合法。
- 地址转换:如果访问合法且页在内存中,MMU将虚拟页号转换为物理页框号(PFN),结合页内偏移生成物理地址(PA)。
- 缺页处理:如果PTE的存在位为0(页不在物理内存中),MMU触发缺页异常(Page Fault),由操作系统内核处理。
硬件加速:为了加速地址转换,现代CPU都集成了TLB(Translation Lookaside Buffer,转译后备缓冲器),它是MMU内部的一个高速缓存,用于缓存最近使用的页表项,避免每次转换都访问内存中的页表。
1.3 Linux内存管理子系统架构
Linux内核的内存管理子系统是一个分层、模块化的复杂系统,从下到上可以分为以下几个关键层次:
- 硬件抽象层:与CPU架构相关的页表操作、TLB刷新、MMU配置等,位于
arch/目录下。 - 物理内存管理:负责物理页框的分配与回收,核心是伙伴系统(Buddy System)和slab分配器。
- 虚拟内存管理:管理进程的虚拟地址空间,包括VMA(Virtual Memory Area)操作、缺页异常处理、内存映射等。
- 内核内存分配器:提供
kmalloc、vmalloc、alloc_pages等接口,供内核其他模块使用。 - 用户空间接口:通过系统调用(如
brk、mmap、munmap)向用户进程提供服务。
注意:Linux内存管理子系统的代码量超过10万行,是内核中最复杂、最核心的子系统之一。理解其架构层次是深入分析内存问题的前提。
1.4 页表与地址转换
页表(Page Table)是虚拟地址到物理地址映射的核心数据结构。在x86-64架构下,Linux使用四级页表(4-Level Page Table)进行地址转换:
| 页表层级 | 名称 | 索引位数 | 描述 |
|---|---|---|---|
| L0 | PGD(Page Global Directory) | 9 bits | 全局页目录,每个进程一个 |
| L1 | P4D(Page 4th Directory) | 9 bits | 四级页目录,x86-64引入 |
| L2 | PUD(Page Upper Directory) | 9 bits | 上级页目录 |
| L3 | PMD(Page Middle Directory) | 9 bits | 中间页目录 |
| L4 | PTE(Page Table Entry) | 9 bits | 页表项,指向物理页框 |
虚拟地址的组成结构(48位地址空间):
63 48|47 39|38 30|29 21|20 12|11 0
+-------------+---------+---------+---------+---------+-----------+
| 符号扩展 | PGD | PUD | PMD | PTE | 页内偏移 |
| (16 bits) | (9 bits)| (9 bits)| (9 bits)| (9 bits)| (12 bits) |
+-------------+---------+---------+---------+---------+-----------+
|<------- 页号 (36 bits) ------>|<-- 偏移 -->|
关键点:四级页表的设计使得页表本身可以按需分配,不需要为整个虚拟地址空间预先分配所有页表。每个进程的PGD只包含512个条目(2^9),未使用的地址范围对应的下级页表可以完全不存在,大大节省了内存。
1.5 本章小结
物理内存是硬件基础,虚拟内存是操作系统提供的抽象。MMU作为硬件加速器,负责高效、安全地完成地址转换。Linux内存管理子系统通过分层架构,将物理内存管理、虚拟内存管理、内核分配器和用户接口有机整合,为整个系统提供稳定、高效的内存服务。理解这些基本概念是后续深入学习页表分配和MMU协同工作的前提。