人人都能学编程
English 开始学习
核心 · 操作系统第 3 课 / 共 6 课免费阅读

虚拟内存与分页 · 操作系统

为什么每个程序都以为自己独占了全部内存?

课程目录

为什么需要它

两个程序可以都用地址 0x1000 而不冲突,一个程序崩溃不会破坏另一个,能运行的程序比内存装得下的还多。这三件事都来自虚拟内存。它是很多面试题的答案,也能解释「段错误」这类报错,以及换页导致的变慢。

直觉理解

内存被切成固定大小的页(通常 4 KB)。每个进程有一张页表:虚拟页号 → 物理页框号。

翻译一个虚拟地址:

  1. 页号 = 地址 // 页大小
  2. 偏移 = 地址 % 页大小
  3. 在页表里查这个页 → 页框
  4. 物理地址 = 页框 × 页大小 + 偏移

页表里没有的页(或者标记为「在磁盘上」)会引发缺页:操作系统把它载入;如果地址根本不合法,就杀掉进程(段错误)。

定义

页表

A per-process map from virtual page numbers to physical frames, with flags such as present, writable and user-accessible.
每个进程一张的映射表,从虚拟页号映射到物理页框,还带着「在内存中」「可写」「用户可访问」等标志。

缺页 Page fault

An access to a page that isn't currently mapped in RAM. The OS either loads it from disk or, for an invalid address, ends the process.
访问了当前没有映射在内存里的页。操作系统要么从磁盘把它载入,要么在地址非法时结束进程。

示例

翻译一个地址

动手试试

用 100 字节的页让算术好读一些。真实系统用 4096。

PAGE = 100
page_table = {0: 7, 1: 3, 2: None}

def translate(vaddr):
    page, offset = vaddr // PAGE, vaddr % PAGE
    frame = page_table.get(page)
    if frame is None:
        return f"page fault (page {page})"
    return frame * PAGE + offset

print(translate(42))
print(translate(150))
print(translate(230))
逐步执行
  1. L542 在第 0 页,偏移 42。
  2. L9第 0 页在第 7 个页框:742。742
  3. L12第 1 页,偏移 50,页框 3。350
  4. L13第 2 页不在内存里。page fault (page 2)

常见错误

以为虚拟地址就是物理地址

程序打印出来的地址是虚拟的。两个进程打印出同一个地址,看的其实是不同的物理内存。

把交换空间当免费内存

内存满了之后,页会被移到磁盘,而磁盘慢几千倍。不停换页(抖动)的机器会慢得像爬。

小测验

1. 这段代码会输出什么?

PAGE = 4096
addr = 9000
print(addr // PAGE, addr % PAGE)
  1. A
    2 808
  2. B
    9 0
  3. C
    2 9000
查看答案

答案:A

2 × 4096 = 8192,9000 − 8192 = 808。

2. 一个程序读取了一个不属于它任何页的地址。会发生什么?

  1. A操作系统以段错误终止它
  2. B它读到了另一个程序的内存
  3. C它读到 0
查看答案

答案:A

这个缺页无法解决,于是操作系统结束这个进程。这种隔离正是目的所在。

动手练习

3 道练习,分三层:先预测程序的输出,再按新需求改程序,最后从零写一个。代码在浏览器里运行,提交马上判题。

  1. 预测输出手工翻译

    准确写出这段程序的输出。

  2. 改需求遵守只读页

    现在页表的每一项是 (页框, 可写)。access(table, vaddr, write) 应该返回物理地址;页没有映射时返回 "fault";向不可写的页写入时返回 "protection"。加上这个保护检查。

  3. 从零写两个进程,同一个地址

    写函数 physical(tables, pid, vaddr, page_size),tables 把每个进程 id 映射到它自己的页表({页: 页框})。返回物理地址;该进程没有这个页时返回 None。

在互动课里练这一课

打开互动课,这些例子都能直接改、直接运行,练习题提交马上判题。免费开始,不用注册。

互动课按顺序解锁:前面的课还没学,会先带你到课程地图。

本课术语

术语中文英文定义
Virtual memory虚拟内存Each process sees its own address space, mapped to RAM by the OS.
Page页A fixed-size block of memory, often 4 KB.
Page fault缺页Access to a page not currently in RAM.
Segmentation fault段错误The OS stopping a process that accessed memory it doesn't own.