工作集与内存抖动
本章为进阶内容,零基础读者可以跳过,不影响后续阅读。
复习
- 缺页异常:访问的页面不在内存时 CPU 和内核怎样配合
- 按需加载与交换空间:只把眼下需要的页面放进内存
- 页面置换:内存装满后应该换出哪一页
TL;DR
- 工作集:进程在一段时间里频繁访问的那一簇页
- 如果分给进程的内存装不下它的工作集,就会频繁缺页
- 频繁换页、忙着搬进搬出却几乎不干正事的现象,叫内存抖动(thrashing)
- 解决办法:给足内存,或暂时减少同时运行的进程
正文
页面置换算法再聪明,也架不住一种最坏的局面:内存根本不够用。这时会发生一种可怕的病——抖动。
工作集
先说一个概念。程序的访问有强烈的局部性:在任意一段时间里,它真正反复用到的,往往只是一小簇页。
这一小簇页,就叫进程的工作集(working set)。它像一个人当前正在用的工作台:桌上摊开的就那么几样东西,别的东西暂时收在柜子里。
抖动是怎么发生的
如果分给某进程的物理内存,小于它的工作集,麻烦就来了:
- 进程要用到某页,但页不在内存 → 缺页
- 内核换进这页,只能先换出别的页
- 可被换出的,恰恰是工作集里的另一页
- 下次进程又要用它 → 再次缺页……
于是系统陷入一个死循环:不停地换页,却永远凑不齐需要的那一簇。CPU 大量时间不是在计算,而是在等磁盘换页。
可用内存 < 工作集
↓
频繁缺页 → 不停换入换出 → CPU 空等磁盘 → 有效吞吐骤降
这种“忙着换页却几乎不做事”的状态,就是抖动(thrashing)。此时磁盘灯狂闪、系统卡得像死机,可 CPU 利用率却可能很低——因为 CPU 一直在等 I/O。
怎么治
抖动的根源是“内存不够装工作集”,所以对策也就两条路:
- 加内存:最直接,但受硬件限制
- 减少并发:暂时挂起一些进程,把内存让给剩下的,让它们的工作集能装得下
操作系统的调度器常会盯着缺页率:一旦发现某个进程缺页太频繁,就把它换出内存、暂停一阵;等内存宽松了再放回来。让内存装得下当前进程的工作集,是避免抖动的核心。
思考题
抖动的时候,CPU 利用率可能反而很低。为什么一块磁盘的“忙碌”,会表现为 CPU 的“空闲”?这说明观察性能时要注意什么?
小结
知识点
- 工作集:进程近期频繁访问的一簇页
- 内存小于工作集会导致频繁缺页
- 抖动:忙着换页、几乎不做正事
- 对策:增加内存或减少并发进程
参考资料
- Wikipedia(zh):工作集:working set
- Wikipedia(zh):抖动:thrashing
思考题答案(仅供参考)
因为抖动的瓶颈在磁盘 I/O:进程频繁缺页,CPU 发出读写请求后只能等磁盘,自己闲着。CPU 利用率低,不是因为没活干,而是因为“活被磁盘卡住了”。这提醒我们:观察性能不能只盯一个指标。CPU 空闲未必是好事,也可能说明它在等某个更慢的部件;磁盘或 I/O 的繁忙,往往才是真正的原因。分清“瓶颈在哪”,是性能分析的第一步。
协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
封面图
设计师 | 南国微雪