1. 认识内存映射
1.1 虚拟内存
虚拟内存就是我们进程认为的内存,比如取地址操作( &array ),获取的就是虚拟地址。
虚拟内存布局:它被精心划分为多个具有特定用途的区域(段),每个区域有明确的起始和结束地址。

这是一个格式化的、有明确语义的布局。每个进程都有这样一份完全相同的"蓝图",只是内容不同。
1.2 RAM(物理内存)
真实存储数据的位置,无结构的页框数组物理内存,没有语义分区。它就是一组连续的、大小相等的页框(Page Frame),每个页框由物理地址唯一编号(如 0x1000, 0x2000)。RAM本身不知道哪里是代码、哪里是堆,需要加载数据就拿一个空闲的物理框用于数据存放。
1.3 页表
页表 :记录虚拟页号和物理页框号(不完全是,后面解释)之间的映射关系,每个进程都有一个页表。

页 :内存大小单位,大小是4KB,在内存空间(0x00000000~0xffffffff)中以4KB(2^12=4096B,1KB=1024B)大小为一页进行划分,方便地址快速定位。
地址和页号的关系:物理地址=物理页框号*页大小(4KB)+偏移量
页表: 虚拟页框号 物理页框号
---------------------------
| | |
| 0x12345 | 0xabcde |
---------------------------
虚拟地址0x12345678,页大小4KB(2^12,12字节)
--->虚拟页号0x12345 偏移量0x678
-----> 物理地址: 0xabcde*0x1000+0x678=0xabcde678
// 将虚拟地址的高20位替换位物理叶框号
1.4 磁盘
存储大量文件,文件需要被加载入RAM中,才能被CPU使用。
2. 数据载出的过程
前提认识:
CPU的内存管理单元(MMU)在执行任何内存访问前,都会先查询页表。页表中的每个条目都包含一组标志位,其中最关键的是 "存在位(Present Bit)"。
判断逻辑分两步:
- 查询存在位:MMU 检查页表条目中的"存在位"。
- 存在位 = 1:表示该虚拟页当前就在物理内存中。页表条目里存的是物理页框号。(命中)
- 存在位 = 0:表示该虚拟页不在物理内存中。页表条目里存的是磁盘地址。(缺页)
- 触发缺页中断:当 MMU 发现"存在位 = 0"时,它不会自己去磁盘找数据,而是立即触发一个缺页中断(Page Fault),把控制权交给操作系统内核。
从磁盘(虚拟内存文件) 把缺失的数据读回RAM
重新修改页表,指向RAM中的新位置
最后让进程继续执行
- 当一个新进程创建,内核会为进程分配虚拟内存和创建页表,页表项是虚拟地址和磁盘地址的映射关系。
- 进程需要数据,检查页表对应的虚拟地址有无相关的物理内存的映射(看存在位),有就直接找到对应的RAM上的数据加载到CPU缓存
- 当CPU开始执行进程的第一条指令时,它发现该指令的虚拟地址对应的页表项标记为"不在内存中"。
- 触发缺页异常:这会触发一个CPU中断,称为缺页异常。
- 操作系统介入处理,操作系统接管控制权: 它检查这个虚拟地址是合法的。 然后,它从物理内存中找到一个空闲的页框(物理页)。操作系统有一个空闲页框列表,它会从这里取一个可用的物理页。操作系统将缺失的代码/数据从磁盘上的可执行文件读入到这个物理页框中。
- 更新页表:修改进程的页表,将虚拟地址映射到这个刚分配的物理页框上(对应一个新的物理页框号),并标记为"在内存中"、"可读"、"可执行"。
- 恢复执行:操作系统返回到被中断的进程,CPU重新执行那条指令。这次,页表已经有了有效的映射,MMU(内存管理单元)可以成功地将虚拟地址翻译成物理地址,程序得以正常运行。


物理页框号替换磁盘地址叫做页表条目更新,是缺页中断处理的核心步骤。具体流程如下:
缺页前:页表条目里存的是磁盘地址(比如"数据在swap分区的第1024块"),状态位标记为"无效"。
缺页发生时:
- CPU发现状态为"无效",触发缺页中断。
- 操作系统从该条目中读出磁盘地址,根据这个地址把数据加载到物理内存中的一个空闲页框(假设页框号为 0x8A3F)。
- 替换(关键步骤)
操作系统用新的物理页框号 0x8A3F 覆盖掉条目里原来的磁盘地址,同时把状态位改为"有效"。
- 缺页后:页表条目里存的是物理页框号 0x8A3F,指向RAM中的数据副本。原来的磁盘地址被丢弃(直到这个页再次被换出,才会重新填入新的磁盘地址)。
3. 数据载入的过程
将数据写回磁盘,然后清除其"存在位",并将页表条目中的物理地址改为磁盘地址。
数据被换出到磁盘时,OS会把它的磁盘地址存好;被换回时,又根据这个地址去找。