操作系统复习(六)

覆盖技术

覆盖技术(Overlay) 是早期计算机操作系统中,为了在物理内存容量极小(比如只有几十KB)的条件下,运行比物理内存大得多的程序,而采用的一种手动内存管理技术。

简单来说,它的核心思想是:“内存装不下整个程序,那就把它拆成几块,哪块要用就加载哪块,不用的块就丢弃或覆盖掉。”

对换技术

就是把内存中暂时不用的程序整个换出外存中,腾出内存供要运行的程序使用。

1. 什么是对换技术?(Swapping)

定义:由操作系统控制,以整个进程为单位,将内存中某个暂时不能运行的进程的全部地址空间(代码+数据+堆栈) 一次性写入磁盘的“对换区”,从而腾出物理内存;当该进程具备运行条件时,再由操作系统一次性将其全部读回内存。

核心特征“整体进出,一次搬完”

2. 什么情况下会换出?(触发时机)

不是随便就换的,操作系统遵循以下原则选择换出进程:

  • 阻塞态进程优先:正在等待I/O(如等待键盘输入、磁盘读写)的进程,短时间内用不到CPU,首选换出
  • 低优先级进程:在多道批处理或分时系统中,当内存紧张且所有进程都在就绪态时,优先换出优先级最低或剩余时间最长的进程。
  • 内存紧缺预警:系统检测到空闲物理内存低于安全阈值时,启动交换。

注意:被换出的进程是**“暂时”**不运行的,它的状态会被保存在PCB中,等I/O完成或轮到它时再换入。

3. 对换技术 vs 覆盖技术(考试必区分)

这是两者最核心的区别,千万不能混淆:

对比维度 对换技术(Swapping) 覆盖技术(Overlay)
管理主体 操作系统(内核自动完成,对程序员透明) 程序员(手动编码控制加载和覆盖)
操作单位 整个进程(完整的地址空间) 进程内部的程序段(部分模块)
空间关系 内存中一个进程的空间与另一个进程的空间交换(换出A,换入B) 同一进程内部,不同模块共享同一块内存区域(互相覆盖)
目标 宏观上让多个进程分时复用物理内存 微观上让一个大程序在有限内存中运行
当前状态 演变为虚拟内存的换页机制,纯整体交换已淘汰 已被虚拟内存彻底取代(操作系统自动分页)

4. 为什么纯“整体对换”在现代操作系统中也淘汰了?

虽然它比覆盖技术进步(由OS自动管理),但依然存在致命缺陷:I/O开销极大

  • 现代一个进程动辄几百MB甚至几个GB,如果每次调度都要从磁盘换进换出整个进程,磁盘I/O会成为巨大的瓶颈,系统会陷入频繁的“抖动”。
  • 现代改良方案:现代操作系统(如Linux)不再进行“整体进程交换”,而是采用请求分页(Demand Paging) 技术,将交换粒度从“整个进程”缩小为“4KB的页面”。只换出那些长期未被访问的页面,而非整坨进程。

总结

一次性把整个暂时不运行的程序搬到磁盘。但要注意区分:覆盖是同一程序的内部模块“手动覆盖”,对换是不同程序之间的“整体换出换入”。在对换的基础上,现代系统进化出了更精细的请求分页(虚拟内存),用“页面”替代了“进程”作为交换单位,大大减少了磁盘I/O压力。

虚拟存储技术

它是一种内存管理技术,将程序的逻辑地址空间与物理内存地址空间分离。

  • 逻辑空间(虚拟空间):程序员/编译器等看到的地址(如 0x0000 ~ 0xFFFF…),可以远大于物理内存。
  • 物理空间(实际内存):硬件上真实存在的RAM条容量。

核心机制:程序不必全部装入内存才能运行,只需装入当前即将执行的部分即可。其余部分存放在磁盘的“交换区”或“页面文件”中,需要时再自动调入。

Belady异常

Belady异常(Belady’s Anomaly),是指在使用先进先出(FIFO)页面置换算法时,分配给进程的物理内存块(页框)增加,缺页中断(缺页次数)反而增多的反常现象。

这完全违背了我们的直觉——“内存越大,性能应该越好”。它是由Belady在1969年发现的,因此以他的名字命名。


经典演示案例(手把手推演)

使用著名的Belady异常访问序列:

1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5

情况一:分配 3 个内存块(FIFO算法)

置换过程(括号内为被淘汰的页):

访问页 内存块状态(队首→队尾) 是否缺页
1 1 ✔️ (1)
2 1, 2 ✔️ (2)
3 1, 2, 3 ✔️ (3)
4 2, 3, 4 (淘汰1) ✔️ (4)
1 3, 4, 1 (淘汰2) ✔️ (5)
2 4, 1, 2 (淘汰3) ✔️ (6)
5 1, 2, 5 (淘汰4) ✔️ (7)
1 1, 2, 5 命中
2 1, 2, 5 命中
3 2, 5, 3 (淘汰1) ✔️ (8)
4 5, 3, 4 (淘汰2) ✔️ (9)
5 5, 3, 4 命中

3个内存块时,缺页次数 = 9次。


情况二:分配 4 个内存块(同样用FIFO)
访问页 内存块状态(队首→队尾) 是否缺页
1 1 ✔️ (1)
2 1, 2 ✔️ (2)
3 1, 2, 3 ✔️ (3)
4 1, 2, 3, 4 ✔️ (4)
1 1, 2, 3, 4 命中
2 1, 2, 3, 4 命中
5 2, 3, 4, 5 (淘汰1) ✔️ (5)
1 3, 4, 5, 1 (淘汰2) ✔️ (6)
2 4, 5, 1, 2 (淘汰3) ✔️ (7)
3 5, 1, 2, 3 (淘汰4) ✔️ (8)
4 1, 2, 3, 4 (淘汰5) ✔️ (9)
5 2, 3, 4, 5 (淘汰1) ✔️ (10)

4个内存块时,缺页次数 = 10次。

结论:内存块从 3 个增加到 4 个,缺页次数反而从 9 次上升到了 10 次——这就是Belady异常。


为什么FIFO会出现这种“反直觉”现象?

  • FIFO只关注年龄:它淘汰的是在内存中停留时间最长的页,而不在乎这个页是否马上要用。
  • 增加内存块改变了“淘汰时间窗口”:当你有3个块时,某些关键页(如页1)恰好会在“安全期”被淘汰;当你有4个块时,淘汰节奏被打乱,导致一个本不该淘汰的页(如页5)在关键节点被保留了下来,反而把另一些更早需要用到的页挤出去了,从而引发后续更多的连续缺页。

哪些算法不会发生Belady异常?

  • LRU(最近最少使用)最佳置换算法(OPT) 等算法具有 “栈性质”(Stack Property)
  • 栈性质意味着:内存块数增加时,任意时刻内存中驻留的页面集合,一定是块数较少时的集合的超集(即包含关系)。增加内存只会增加保留的页面,绝不会丢掉块数少时能保留的页面,因此缺页次数必然减少或不变。

正是由于FIFO存在这种致命缺陷,现代操作系统通常不会将FIFO用作主置换算法,而更多地使用LRU的近似算法(如Clock算法)。

分区存储管理

分区存储管理,是早期多道程序系统中,为了支持多个程序同时在内存中运行而采用的一种连续分配存储管理方案。

它的核心思想是把内存的用户区域(除操作系统占用外的部分)划分为若干个分区,每个分区在任意时刻只装入一道程序,从而实现多道程序并发执行

1. 核心原理:物理上连续,一个分区一道程序

分区存储管理的核心假设是:程序必须装入一个连续的内存区域才能运行

系统通过基址寄存器限长寄存器(或上界/下界寄存器)来实现地址映射和保护:

  • 逻辑地址 → 物理地址:程序中的地址(逻辑地址) + 基址寄存器中的基值 = 实际物理内存地址。
  • 保护机制:限长寄存器检查该地址是否在分区边界内,防止越界。

2. 两大类:固定分区 vs 动态分区(可变分区)

对比维度 固定分区(静态分区) 动态分区(可变分区)
划分时机 系统初始化时划分,分区大小和数量固定不变。 作业装入时动态划分,分区大小随作业需求而定。
分区数量 固定,内存中同时存在的分区数量不变。 动态变化,随着进程创建/撤销而增减分区。
作业大小限制 作业必须 ≤ 最大分区大小(若作业小于分区,则产生内部碎片)。 作业大小受限于当前剩余总内存(无内部碎片,但会产生外部碎片)。
内存利用率 较低(内部碎片浪费)。 较高(但需解决外部碎片问题)。
典型算法 无复杂放置策略(依次装入对应分区)。 首次适应、最佳适应、最差适应、循环首次适应(用于管理空闲分区表/链)。

3. 动态分区的放置算法

在动态分区中,当有多个空闲分区可供选择时,采用哪种策略直接影响碎片情况:

  • 首次适应(First Fit):从头开始找,找到第一个能装下的空闲分区。实现简单,综合性能较好(保留大块分区在尾部)。
  • 最佳适应(Best Fit):遍历所有空闲分区,找最小且能装下的分区。会产生大量难以利用的外部碎片
  • 最差适应(Worst Fit):找最大的空闲分区。产生的大碎片少,但容易耗尽大块内存。
  • 循环首次适应(Next Fit):从上一次结束位置继续往后找,避免了频繁扫描头部,但内存利用率通常不如首次适应。

4. 优点与缺点

优点
  1. 实现简单:硬件支持仅需基址寄存器和限长寄存器,地址变换速度快。
  2. 管理开销小:无需维护复杂的页表或段表。
  3. 支持多道程序:实现了多道程序并发,提升了CPU和内存利用率(相比单一连续分配)。
缺点
  1. 碎片问题严重
    • 内部碎片(固定分区):分配给作业的分区有剩余空间无法使用。
    • 外部碎片(动态分区):随着进程的撤销和装入,内存中会散布大量小碎片,虽然总和足以装入一个新作业,但不连续,导致无法利用(需要采用紧凑(Compaction) 技术来移动进程,但开销极大)。
  2. 作业大小受物理内存限制:一个作业必须一次性全部装入内存才能运行(这一点我们刚刚在“非虚拟存储器”的题中强调过)。如果程序大于物理内存,仅靠分区管理无法运行。
  3. 不支持虚拟内存:无法实现程序的部分装入和按需换入换出,无法突破物理内存的容量限制。
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐