PromleeBlog

posting thumbnail
什么是虚拟内存?——每天 10 分钟操作系统,第 11 天

📅

开始之前 🔗

我们使用的程序需要的内存,往往比想象中多得多,但物理 RAM 的容量有限。这时,操作系统就会用到
虚拟内存(Virtual Memory)
。
本文从虚拟内存的概念讲起,逐步介绍如何调入和置换页面,以及容易混淆的写时复制(Copy-on-Write),力求让小朋友也能读懂。

什么是虚拟内存? 🔗

虚拟内存
是操作系统提供比物理内存更大的地址空间的技术。程序可以像拥有大量内存一样运行,实际上只有一部分数据在内存中,其余部分存放在磁盘上。
这就像住在一间小屋里,另设一个仓库,只把眼下需要的物品拿出来。

为什么需要虚拟内存? 🔗


按需分页(Demand Paging) 🔗

虚拟内存不会从一开始就把所有页面放进内存,而是
需要时才
加载。这称为
按需分页(Demand Paging)
。
📦 就像只从仓库取出当前要用的物品一样。

工作方式 🔗

  1. 启动程序 → 只把最初需要的几个页面装入内存。
  2. 运行中需要其他页面 → 触发
    缺页异常(Page Fault)
    。
  3. 从磁盘读取相应页面 → 装入内存。
  4. 继续执行。

示例流程 🔗

  1. 一个进程有 10 个页面,但内存中只装入 3 个。
  2. 当需要其余页面时,操作系统检测到缺页异常。
  3. 把所需页面从磁盘复制到 RAM。
按需分页让有限的内存能支持更大的地址空间。

页面置换(Page Replacement) 🔗

如果需要把新页面装入内存,但内存已经满了,该怎么办?
🎒 这就像书包里装了太多书,需要先拿出不读的书,再放进新书。
这时,操作系统使用
页面置换算法
决定换出哪个页面。
常见算法如下。

FIFO 🔗

先换出最早装入的页面。
페이지 프레임: 3개
요청: A, B, C, A, D

→ 적재 순서: A, B, C
→ A는 재사용됨
→ D 요청 시, A가 가장 먼저 들어왔으므로 A 제거
→ 페이지 교체: A → D
换出最长时间未被使用的页面。
페이지 프레임: 3개
요청: A, B, C, A, D

→ A, B, C 적재
→ A 재사용됨 → A는 최근 사용됨
→ D 요청 → B가 가장 오래 사용되지 않음 → B 제거
→ 페이지 교체: B → D

Optimal 🔗

换出未来最晚才会被访问的页面。由于必须知道未来的访问情况,实际很难采用。
페이지 프레임: 3개
요청: A, B, C, A, D, B

→ A, B, C 적재
→ A 재사용됨
→ D 요청 → C는 앞으로 사용되지 않음 → C 제거
→ B 요청 → A는 안 쓰고 D는 나중에 → D 제거 (미래 기준)

写时复制(Copy-on-Write) 🔗

两个进程使用相同数据时,先
共享
同一个页面,
等其中一方尝试修改时才复制
。
📄 这就像两人只阅读时可以共用一份文件,等有人需要修改时,再单独为他复制一份。

工作方式 🔗

  1. 父进程创建子进程时,两者共享内存。
  2. 两个进程都可以读取内存。
  3. 一方尝试修改数据时 →
    只复制并分离相应页面
    。
这种技术常用于在
fork()
之后高效管理内存。

内存压缩(Memory Compression) 🔗

有些操作系统会
压缩未使用的数据,让更多数据留在内存中
,以此代替交换到磁盘。

内核内存分配 🔗

除了用户程序,内核也会使用虚拟内存。
操作系统内部也需要申请和释放内存,因此内核有自己的内存分配器,例如 slab 和 buddy。
可以把内核想成“操作系统里的一个小程序”。它也需要内存!

总结 🔗

本文介绍了虚拟内存的核心概念,以及操作系统如何通过按需分页、页面置换和写时复制等方法高效利用内存。
下一篇将介绍大容量存储设备的结构与磁盘调度。

参考资料 🔗

    什么是虚拟内存?——每天 10 分钟操作系统,第 11 天 | PromleeBlog