《Operating Systems: Three Easy Pieces》学习笔记(十九) VAX/VMS虚拟内存系统
数字设备公司(DEC)在 20 世纪 70 年代末推出了 VAX-11 小型机体系结构。该系统的操作系统被称为 VAX/VMS(或者简单的 VMS),其主要架构师之一是 Dave Cutler,他后来领导开发了微软 Windows NT
只讲重点,直接看原文就行
分段的 FIFO
防止
有“自私贪婪的内存”(memory hog)—— 一些程序占用大量内存
, 使其他程序难以运行。
每个进程都有一个可以保存在内存中的最大页数,称为驻留集大小
(Resident Set Size,RSS
)。每个页都保存在 FIFO 列表中。当一个进程超过
其 RSS
时,“先入”的页被驱逐
。决定了进程不能占用过大内存
纯粹的 FIFO 并不是特别好。为了提高 FIFO 的性能,VMS 引入了两个
二次机会列表
(second-chance list),页在从内存中被踢出之前被放在其中。具体来说, 是全局
的干净页空闲列表
和脏页列表
。当进程 P
超过其 RSS 时,将从其每个进程的 FIFO 中移除
一个页。如果干净(未修改)
,则将其放在干净页列表
的末尾。如果脏(已修改)
,则 将其放在脏页列表
的末尾。
如果另一个进程 Q
需要一个空闲页,它会从全局干净列表
中取出第一个
空闲页。但是, 如果原来的进程 P
在回收之前在该页上出现页错误
(不在物理内存中,在磁盘中),则 P 会从空闲(或脏)列表中回收
,从而避免昂贵的磁盘访问。这些全局二次机会列表越大,分段的 FIFO 算法越接近 LRU
页聚集
通过聚集
,VMS 将大批量的页从全局脏列表
中分组
到一起,并将它们一举写入
磁盘(从而使它们变干净)。
写时复制(copy-on-write,COW)
如果操作系统需要将一个页面从一个地址空间复制到
另一个地址空间,不是实际复制
它,而是将其映射
到目标地址空间(相当于两个空间是共享的,还是同一个),并在两个地址空间中将其标记为只读
。如果两个地址空间都只读取页面,则不会采取进一步的操作,因此操作系统已经实现了快速复制而不实际移动任何数据。
如果其中一个地址空间确实尝试写入页面,就会陷入操作系统。操作系统会注意到该页面是一个 COW 页面,因此(惰性地)分配一个新页
,填充数据,并将这个新页映射到错误处理的地址空间。该进程然后继续,现在有了该页的私人副本。
例子:
fork()会创建调用者地址空间的精确副本
,就是原来的程序要复制一份,fork 出的新程序和原来的是一样的,如果后面还有 exec 替换不同的程序,那这个复制操作实际上没有意义。对于大的地址空间,这样的复制过程很慢
,并且是数据密集的。更糟糕的是,大部分地址空间会被随后的 exec()
调用立即覆盖
,它用即将执行的程序覆盖调用进程的地址空间。通过改为执行写时复制的 fork(),操作系统避免了大量不必要的复制,从而保留了正确的语义,同时提高了性能。