编程与 AI16 分钟阅读更新于 2026-08-04

Linux 虚拟内存怎么工作:分页、页表与缺页异常

解释 Linux 虚拟内存、分页、页表、MMU 和缺页异常的关系,并说明多级页表如何减少地址映射的空间开销。

相关工具

虚拟内存把地址空间和物理内存分开

程序编写时使用的是虚拟地址,处理器执行指令时也先产生虚拟地址。物理内存则是当前真正装有页面的硬件资源,二者之间并不是一一对应的固定关系。一个进程看到的地址空间可以比当前分给它的物理内存大得多。

虚拟内存的价值不只是“把内存变大”。它让每个进程拥有相对独立的地址空间,让系统可以按页面装入和回收数据,也让内核能够在地址转换时检查访问权限。程序因此可以用连续的地址表达逻辑结构,系统则在后台管理分散的物理页面。

进程虚拟页面映射到部分物理页框并由页表维护关系的结构图
虚拟地址空间与物理内存的关系

进程看到连续的虚拟页面,实际只把部分页面映射到物理页框,其他页面可以暂未装入。

分页把地址空间切成固定大小的页面

分页会把虚拟地址空间切成固定大小的页面,把物理内存切成同样大小的页框。虚拟页面可以映射到任意空闲物理页框,不要求整个进程在物理内存中连续存放。Linux 中常见的页面大小是 4 KB,但具体大小还可能随处理器架构和系统配置变化。

固定大小让内存分配和回收更规整。系统以页面为单位建立映射、换入换出和设置权限,不必为每个不同长度的区域寻找连续物理空间。代价是最后一个页面可能没有被完全使用,页表也需要为映射关系占用额外空间。

页表记录了什么

页表把虚拟页号映射到物理页框号,并保存页面是否存在、是否可读写、是否可执行以及是否允许用户态访问等标志。处理器进行地址转换时,会先通过虚拟页号找到页表项,再把物理页框号与页内偏移组合成物理地址。

页表项中的存在位很重要。页面可能属于进程的合法地址空间,却暂时没有驻留在物理内存中;这时访问会触发缺页处理。若页面根本没有合法映射,或当前操作违反权限,则不会被当作普通的页面装入请求,而会进入错误处理路径。

MMU 和操作系统如何分工

内存管理单元 MMU 是处理器中的硬件部件,负责根据页表完成地址转换和基础权限检查。它可以在每次内存访问时参与判断,让指令使用虚拟地址时仍然能够到达正确的物理页面。

操作系统负责建立和更新页表,分配物理页框,处理缺页异常,并在进程切换时切换到对应的地址空间。硬件负责快速执行重复的转换,内核负责处理映射关系变化和异常情况,两者共同完成虚拟内存机制。

CPU、MMU、TLB、页表和内核缺页处理之间协作的流程图
MMU 与页表的协作

CPU 产生虚拟地址后,MMU 通过 TLB 或页表查找物理页框,并在失败时交给内核处理。

缺页异常为什么不一定是错误

当程序访问一个尚未装入物理内存的合法页面时,处理器会触发缺页异常。内核检查地址和访问权限后,可能分配一个空闲页框,从可执行文件或交换空间中装入页面,更新页表,最后让程序重新执行刚才的指令。

对程序来说,这次访问看起来只是稍微变慢了,并不意味着程序出错。只有当地址没有合法映射、页面无法装入,或访问操作违反权限时,缺页处理才可能转化为终止进程的错误。判断缺页时,关键是区分“合法但暂未驻留”和“根本不允许访问”。

为什么需要多级页表

如果用一张平坦页表覆盖整个虚拟地址空间,即使进程只使用很小的一部分地址,也可能需要为大量虚拟页面准备页表项。对多个进程来说,页表本身就会占用相当多的内存。

多级页表把地址拆成多个层级,只有真正使用到的地址范围才建立下一级页表。上一级页表负责找到下一级结构,最后一级才定位具体物理页框。它增加了地址查找步骤,却避免了为大片未使用的地址空间提前分配完整映射。TLB 则用来缓存常用的最终结果,减少重复查表。

虚拟地址经过多级页表逐层查找最终得到物理页框的结构图
多级页表按需建立映射

上层页表覆盖较大的地址范围,下层页表只为实际使用的区域建立,节省页表空间。

分页解决了哪些内存管理问题

分页让释放内存可以按页面进行,减少了因为必须寻找大块连续物理空间而产生的外部碎片。进程装入时也不必一次把所有内容放进物理内存,只有正在访问的代码和数据页面才需要驻留。

当物理内存不足时,系统可以选择暂时不活跃的页面写入外部存储,之后再按需装回。这个过程会增加 I/O 延迟,因此页面置换策略、访问局部性和物理内存容量都会影响性能。虚拟内存扩大了可用地址空间,却没有消除物理资源有限这一事实。

地址转换为什么需要 TLB

程序几乎每条指令都可能访问内存。如果每次访问都从多级页表开始查找,地址转换本身就会产生明显开销。TLB 是处理器中的地址转换缓存,用来保存最近使用过的虚拟页到物理页框的映射。

TLB 命中时,MMU 可以快速得到物理页框并继续访问;TLB 未命中时,系统需要进行页表查询,查询成功后通常还会把结果放入 TLB。进程切换、页表更新和权限变化可能影响缓存内容,因此地址转换性能不仅取决于页表层级,也取决于访问局部性。

用一条主线理解 Linux 虚拟内存

程序产生虚拟地址,MMU 根据 TLB 或多级页表寻找物理页框,并检查页面权限。映射有效时,访问继续完成;页面合法但不在物理内存时,内核处理缺页并恢复执行;地址或权限不合法时,系统阻止访问并处理异常。

学习虚拟内存时,不要把页表、缺页、交换和 TLB 当成互不相干的名词。它们共同回答的是同一个问题:如何让进程使用看似连续的地址空间,同时让系统在有限的物理内存上按需映射、保护和调度页面。

常见问题

缺页异常一定表示程序访问了非法地址吗?

不一定。合法页面暂时没有装入物理内存时也会触发缺页异常,内核装入页面后可以恢复程序执行。

多级页表为什么能节省内存?

它只为实际使用到的虚拟地址范围建立下一级页表,不需要为整片未使用的地址空间提前准备全部页表项。

TLB 和页表有什么区别?

页表是由操作系统维护的完整映射结构,TLB 是处理器中保存近期映射结果的高速缓存,命中时可以减少页表查询。