Appearance
虚拟存储性能与改进
2026 大纲 三(二)6 虚拟存储器性能的影响因素及改进方法。
踢得太勤,系统就光顾着搬页面了
这一章走到这里,因果链已经推完了一整圈:连着放会碎 → 散着放 → 地址要翻译 → 内存还是不够 → 那就只装一部分 → 不够就踢一个出去 → 该踢谁有四种算法 → 给每个进程几个页框也有讲究。
现在到了这条链的最后一环,也是它的反噬:如果踢得太勤会怎么样?
答案是系统会进入一种很难看的状态——CPU 几乎全部时间都在等页面换入换出, 真正干活的时间越来越少。这就是抖动(thrashing)。
它的成因写成一行式子就清楚了:
左边是所有进程加起来真正需要的页数,右边是实际能给的。 需求超过供给时,每个进程都分不到够用的页框,于是每个进程都在频繁缺页。
真正麻烦的是它会自我强化。进程都在等换页 ⇒ CPU 空闲率上升 ⇒ 系统看到"CPU 没事干",判断为多道程度不够 ⇒ 再放进来几个进程 ⇒ 每个进程分到的页框更少 ⇒ 缺页更频繁 ⇒ CPU 更空闲……
死结在于:CPU 利用率低有两种成因完全相反的可能—— 真的没进程可跑(该加),和进程全堵在换页 I/O 上(该减)。 只看利用率这一个指标,根本区分不了这两种情况,而加错方向就是抖动的入口。
所以这一节的重点不是"抖动是什么",而是怎么拿到一个能区分两种成因的信号, 以及拿到之后往哪个方向调。四种预防方法各自作用在不同环节, L=S 准则和 PFF 则给出了两条可以直接计算的判据。
一、影响缺页率的四项因素
把因素与"往哪个方向变"分开列——这两件事混在一列里最容易读反:
| 因素 | 该因素变大时 | 缺页率 | 判据 / 代价 |
|---|---|---|---|
| 页面大小 | 页面划分较大 | 降低 | 一次调入的内容更多,覆盖的空间局部性更广;代价是内碎片增大 |
| 分配的物理块数 | 分得越多 | 降低 | 驻留集越接近工作集;但边际收益递减,超过工作集大小后再加块几乎无效 |
| 页面置换算法 | 算法越好 | 降低 | ⚠️ 性能序 OPT > LRU > CLOCK > FIFO 与缺页率序方向相反 |
| 程序固有特性 | 局部化程度越高 | 降低 | 由程序的编制方法决定,是四项里唯一由应用自己控制的 |
页面大小这一行值得单独展开,因为它是一组取舍而不是单调关系:
| 页面变大 | 好的一侧 | 坏的一侧 |
|---|---|---|
| 缺页率 | 降低 | —— |
| 页表规模 | 页数减少,页表变小 | —— |
| 内碎片 | —— | 进程末页填不满的部分变大,平均浪费半页 |
| 单次调页的 I/O 量 | —— | 一次缺页要传的数据更多,单次缺页更贵;且调进来的内容未必都用得上 |
最后一项因素则可以直接看到代码上——同样的数组赋值,按行优先和按列优先的缺页率可能差异巨大:
c
// 按行优先 —— 局部性好,缺页少
for (int i = 0; i < 1024; i++)
for (int j = 0; j < 1024; j++)
a[i][j] = 0;
// 按列优先 —— 局部性差,缺页多
for (int j = 0; j < 1024; j++)
for (int i = 0; i < 1024; i++)
a[i][j] = 0;C 语言数组按行存储,a[i][0..1023] 在内存里连续。按行遍历时一次调入的页面会被连着用完才换下一页;按列遍历则每访问一个元素就跳过一整行的距离,页框数不够就会不停缺页。
二、抖动为什么会自我强化
抖动(也叫颠簸)指进程频繁地换入换出页面,大部分时间都花在页面调度上,几乎无法推进实际计算。
环路的入口正是 E → F 那一步:CPU 利用率低这个现象有两种完全相反的成因,只看它无法区分,加错了就正反馈起飞。
CPU利用率
↑
| ╱‾‾╲
| ╱ ╲
| ╱ ╲
| ╱ ╲ ← 抖动开始
|╱ ╲____
+------------------------→ 多道程度随着进程数增加,CPU 利用率先急剧上升,到某一点后增速放缓,到最大值后先缓慢下降,越过某个临界点后加速下降并趋于 0——趋于 0 的那一段就是系统已经进入抖动。所以存在一个最优多道程度。
三、四种预防方法作用在不同环节
| 方法 | 做什么 | 位置与局限 |
|---|---|---|
| ① 采取局部置换策略 | 可变分配下规定进程缺页时只能在自己的空间内置换,不许抢别人的页框 | 只是把伤害局部化:抖动的那个进程仍会长期挂在磁盘 I/O 等待队列上,拉长队列、延长其他进程缺页的处理时间。治标不治本 |
| ② 把工作集算法融入处理机调度 | 发现 CPU 利用率低时不要直接调入新作业,先查每个进程的驻留页面够不够:都够 → 可以调入;有进程不足 → 先给缺页率高的补物理块,此时不引新作业 | 正是针对"CPU 利用率低有两种成因"这个分歧点,用"驻留页面够不够"这个额外信号把两种成因区分开 |
| ③ 利用 L=S 准则调节缺页率 | 比较缺页到达间隔与缺页服务时间,据此决定加还是减多道程度 | 给出一个可算的判据;道理是排队论的到达率与服务率 |
| ④ 选择暂停的进程 | 挂起一部分进程、把腾出的内存分给缺页率偏高的进程,挑选顺序与调度策略保持一致 | 这一条才是真正减少多道程度 |
有了各进程的
两道算例:用 L=S 判断该加还是该减进程、由性能目标反解 PFF 的上下限(想看频率与间隔怎么互转、阈值怎么被缺页处理时间的量级压得极小时展开)
算例一:L=S 判断多道程度(数据自造)
某系统处理一次缺页的平均时间
第一步:把"每秒缺页次数"折算成 L。
第二步:与 S 比较。
第三步:算目标。 要
第四步:折算多道程度。 若 10 个进程的缺页情况大致相当,每个约贡献 40 次/秒,要把总数压到 200 次/秒,多道程度应降到约 5。这里只能说"大致"——挂起进程后留下的进程会分到更多页框,各自的缺页率还会进一步下降,所以真实需要挂起的进程数通常少于 5 个。这个估算给的是上界,实际系统靠反复测量逼近。
算例二:反解 PFF 的上下限(数据自造)
某请求分页系统
第一步:写出关系并反解。
第二步:算上限。
校验:
第三步:算下限。
结论: 缺页率高于
注意
四、改进方法汇总
考纲这一条写的是"影响因素及改进方法"。防抖动只是其中一条线,其余改进散落在全章各处,这里收拢成一张表——每一项都写清它作用在哪一环、降低了
| 改进方法 | 作用环节 | 降低的是什么 | 详见 |
|---|---|---|---|
| TLB(快表) | 地址变换 | 命中时省掉访问页表的那一次访存,直接压低 | 页式管理 |
| 多级页表 / 反置页表 | 页表本身的存储 | 页表不必整体驻留,减少页表占用的页框,等于把页框让给数据 | 页式管理 |
| 合理选择页面大小 | 缺页率 ↔ 内碎片 | 大页压低 | 本篇 §一 |
| 预调页策略 | 调入时机 | 一次调入多个相邻页,减少缺页中断的次数(降低 | 页框分配与回收 |
| 页面缓冲算法(PBA) | 换出路径 | 换出页数据仍保留可直接取回、脏页攒批写盘,减少磁盘 I/O 次数,直接压低 | 页框分配与回收 |
| 改进 CLOCK(优先淘汰干净页) | 置换选择 | 压低脏页概率 | CLOCK 篇 |
| 更好的置换算法(LRU / CLOCK 取代 FIFO) | 置换选择 | 直接压低 | 四篇置换算法 |
| 按比例 / 按优先权分配页框 | 分配 | 让驻留集贴近工作集,压低 | 页框分配与回收 |
| 局部置换、工作集融入调度、L=S、暂停进程、PFF | 多道程度与页框数 | 防抖动——避免 | 本篇 §三 |
| 改善程序局部性(按行遍历) | 应用程序侧 | 压低 | 本篇 §一 |
考点速记
- 影响缺页率的四项因素:页面大小、分配的物理块数、置换算法、程序固有特性(唯一由应用自己控制的一项)。
- ⚠️**"OPT > LRU > CLOCK > FIFO"比的是性能,不是缺页次数——两个序方向正好相反:性能 OPT > LRU > CLOCK > FIFO;缺页率** FIFO > CLOCK > LRU > OPT。认准 OPT 在最好的那一端,另一端就跟着定了。
- "页面越大越好"只在缺页率一个维度上成立:大页压低缺页率、缩小页表,但内碎片增大(平均浪费半页)、单次调页要传更多数据且未必都用得上。所以实际取折中值。
- 抖动的根本原因:
(左边需求、右边供给)。⚠️ 因此扩大交换区容量对抖动无效——瓶颈在物理内存不够分,不在外存不够放。 - ⚠️CPU 利用率低有两种完全相反的成因:真的没进程可跑(该加)/ 进程全堵在换页 I/O 上(该减)。只看利用率无法区分,加错了就是抖动恶性循环的入口。三条可操作判据任选其一:看下降是否伴随缺页率飙升、比
与可用页框数、算 与 。 - L=S 准则:L = 缺页之间的平均时间(到达间隔),S = 平均缺页服务时间。
磁盘空闲、可提高多道程度; 是磁盘与处理机同时满负荷的目标状态; 缺页速度已超过磁盘处理能力、须降低多道程度。 - 为什么 L 小反而是坏事:
意味着请求到达比服务完成还快,排队队列会无限增长——这正是抖动在排队论上的样子。⚠️ 题目常给"每秒缺页多少次",那是频率,取倒数才是 。 - PFF(缺页频率)策略:缺页率 > 上限 ⇒ 给进程增加页框;< 下限 ⇒ 回收部分页框;已无法再增加而仍高 ⇒ 挂起该进程。它从单进程页框数一侧入手,是"可变分配 + 局部置换"的落地形式。
- PFF 的上下限由性能目标反解:
是 的单调递增一次函数,故" 不超过某值"等价于" 不超过某值", 。两条水平线本质是性能目标在缺页率轴上的投影。 - 挑谁挂起:两条判据——释放收益最大(体积较大、一次能释放较多物理块)、沉没成本最小(剩余执行时间最多,挂起它损失的已投入时间最少)。
- 全章性能总账:
。所有改进最终只落在三个量上——压 、压 、压 的等效值。记住这条,就不需要背改进方法的清单。
这一节在真题里被考过的形式:
两道选择题,一道拆
- 问哪些因素影响请求分页系统的有效访存时间(2020-28)。答四条全部:缺页率、磁盘读写时间、内存访问时间、执行缺页处理程序的 CPU 时间。⚠️ 判据就是把
摊开看—— 是缺页率, 是内存访问时间,而 里同时含磁盘 I/O和缺页处理程序的 CPU 时间。四项各占式子里的一个位置,一个都不多余。 - 问哪个因素不会影响系统缺页率(2022-30)。四个选项是页面置换算法、工作集的大小、进程的数量、页缓冲队列的长度。⚠️ 前三项都直接进了速记第一、四条:置换算法决定踢得准不准,工作集大小与进程数量共同决定
与供给的对比。页缓冲队列的长度改变的是"缺页之后有多贵"而不是"缺不缺页"——被换出的页先进队列,再次访问时能直接取回,这确实降低了缺页的代价,但它不改变访问模式,因而不改变缺页率本身。 - 问系统发生抖动时可采取的有效措施(2011-29,同时挂在页框分配标签下,已在页框分配与回收详述)。答仅撤销部分进程——它是唯一真正减少
的操作。
复习优先级:必须拿满,且判据全在一个式子里。 把
易错:把"OPT > LRU > CLOCK > FIFO"当成缺页次数的顺序。那是性能顺序,缺页率的顺序正好相反。
易错:认为页面越大越好。大页压低缺页率,但内碎片增大、单次调页传输量增加。
易错:认为扩大交换区能缓解抖动。瓶颈是物理内存不够分,不是外存不够放。
易错:看到 CPU 利用率低就提高多道程度。两种相反成因都会让利用率低,加错方向正是抖动的入口。
易错:题目给"每秒缺页
次"时直接当作 。那是频率, 要取倒数。
易错:认为
越小越好。 说明请求到达比服务还快,队列会无限增长——这就是抖动。
易错:认为页缓冲队列的长度会影响缺页率。它改变的是缺页的代价,不改变访问模式,因而不改变缺页率。
教材出处
- 缺页率
的定义与影响缺页率的四个因素(① 页面大小:页面划分较大则缺页率较低;② 进程所分配物理块的数目:越多缺页率越低;③ 页面置换算法;④ 程序固有特性:程序编制的局部化程度越高,执行时缺页程度越低):汤小丹《计算机操作系统》5.2.3 节「缺页率」,p162 - 抖动的定义"刚被换出的页很快又要被访问……一个进程在运行中把大部分时间都花费在页面置换工作上":同书 5.3 节开头,p163
- 多道程序度与处理机利用率的曲线(到
达最大,越过 后加速下降趋于 0)、以及产生抖动的根本原因"同时在系统中运行的进程太多,由此分配给每一个进程的物理块太少":同书 5.4.1 节,p169–170 - 抖动的四种预防方法(① 采取局部置换策略;② 把工作集算法融入到处理机调度中;③ 利用"L=S"准则调节缺页率,L 是缺页之间的平均时间、S 是平均缺页服务时间,由 Denning 于 1980 年提出;④ 选择暂停的进程,通常先选优先级最低的):同书 5.4.3 节「"抖动"的预防方法」,p172
- 缺页率与物理块数的关系曲线(物理块数超过某个数目后再增加对缺页率的改善已不明显):同书 5.4.2 节图 5-10,p170–171
相关知识
内存映射文件|页框分配与回收|请求页式管理|OPT 页面置换算法|CLOCK 与改进 CLOCK 算法