page fault 与缺页异常

这页讲的是:程序访问一个地址时,并不代表那一页此刻已经老老实实摆在 CPU 面前。很多时候,内核正是借由 page fault 这次“访问没直接成功”的机会,去补齐映射、拉页进来、扩展栈、做写时复制,或者判定这次访问根本非法。学这页的重点,是理解缺页不等于出错,它常常是虚拟内存正式开始兑现承诺的入口。

这块是什么

page fault 与缺页异常,讲的是当 CPU 发现当前访问的虚拟地址不能直接完成时,怎样把控制权交给内核,由内核判断这是一次正常的按需建页、一次需要从磁盘补数据的缺页、一次写时复制触发,还是一次应该把进程打断的非法访问。它站在 CPU、地址空间、页表、页缓存和进程执行之间,是虚拟内存真正落到运行时的关键入口。

可以把它理解成:程序拿着房间号去开门,发现门后面现在还没准备好。内核这时会判断:是应该临时配钥匙、把家具搬进来、给你分一间新房,还是这扇门本来就不该让你开。

它负责什么

把虚拟地址兑现成可访问内存

  • 访问地址时发现页表项还没准备好
  • 按需建立映射,而不是一开始就把所有页都铺满
  • 让大地址空间和惰性分配真正可行
  • 把“地址存在”和“物理页就绪”这两件事分开

承接按需装入与写时复制

  • 文件页可能要在第一次访问时才真正进内存
  • 匿名页可能在写入时才从共享状态分裂出来
  • 把 fork 之后的复制成本延后到真正写的时候
  • 让内存利用率和启动速度更可控

识别非法访问并终止错误路径

  • 区分“正常缺页”和“越界/权限不对”的访问
  • 在错误场景下触发异常处理或进程终止
  • 帮助系统守住地址空间边界
  • 让错误不是默默污染别人的内存

为什么它不是“内存不够时才会发生”

如果想得太简单会怎样真正关键在哪
把 page fault 理解成纯粹报错会错过它其实是虚拟内存正常工作的一部分。很多缺页本来就是按需映射和按需装入的正式入口。
觉得只有内存紧张才会缺页会忽略首次访问、COW、文件页装入也都会走进来。缺页关心的是“当前访问能不能直接完成”,不只是“系统够不够内存”。
只盯着页表不看进程执行容易看不见缺页会让任务阻塞、唤醒甚至收到错误结果。这既是内存问题,也是执行路径和调度问题。
把所有缺页都当一种事会把匿名页、文件页、写时复制和非法访问混在一起。不同缺页背后代表完全不同的系统语义。

关键概念

概念现在怎么理解
page faultCPU 访问地址时发现当前映射不能直接完成,于是把处理权交给内核。
缺页异常更偏中文语境下的说法,既可能是正常按需补页,也可能是非法访问。
按需分页不是一开始把一切都准备好,而是访问到了再建立或装入。
写时复制先共享、等真正写入时再拆分出私有页的策略。
匿名页 / 文件页前者更像进程自己的内存内容,后者更像来自文件映射或页缓存的数据来源。
权限错误页可能存在,但当前访问方式不被允许,比如该只读却去写。

为什么重要

常见误解

它不负责什么

和其他模块的关系

相关模块关系
页表与地址空间那页讲地址如何组织,这页讲访问失败时系统怎样把那套组织兑现成可运行结果。
页缓存、回收与内存压力文件页缺页常会和页缓存装入、回收后重建、内存压力下的抖动连在一起。
调度器与等待缺页如果需要 I/O 或等待资源,任务就可能睡下,等条件满足后再继续执行。
系统调用与用户空间边界用户程序虽然只看到一次普通访问,但真正失败或补页发生在内核接手之后。
signals 与进程通知非法访问并不是安静失败,很多时候会沿着异常结果变成进程可见的信号后果。

读完这页后,你应该能回答

后面适合继续问:page fault 和 COW 最容易混在哪?缺页为什么会让程序第一次访问某些数据时明显变慢?从非法访问到进程崩溃,中间到底发生了哪些角色切换?