第81期 | 内存满了,先扔谁?

操作系统 · · 九羲科技

上一期讲完缺页,这一期讲缺页之后最难的一步:内存满了,没有空页框,新页住进来之前,先把谁请出去?

一、先进先出,越换越慢

内存满了,缺页处理就多了一步:先选一页牺牲者,腾出页框,再把新页读进来。最省事的选法是先进先出:谁先进内存,谁先走,不管它最近还在不在用。最理想的选法恰恰相反:换掉未来最久才会被用到的那一页,缺页次数最少。可它要预知未来,做不成,只能当一把标尺,拿来量别的算法离最优还有多远。

1969 年,Bélády 给出了一个反常识的例子¹:访问串 1,2,3,4,1,2,5,1,2,3,4,5,用先进先出,3 个页框要缺页 9 次,页框加到 4 个,缺页反而涨到 10 次。内存变多,表现变差。原因不玄:先进先出只认进来的先后,不认最近用没用过,多出来的页框打乱了原先的驱逐顺序,刚好把马上要用的页提前赶了出去。按最近最久未用的思路选,就不会出这种怪事:最近用过的页,大概率还会再用,这就是时间局部性。可真正的最近最久未用,要给所有页排一个全序,硬件代价太大。

折中办法是时钟算法²:把页框排成一圈,指针像钟表指针一样转。每页带一位“被引用过没有”的标记,指针指到哪页,标记是 0 就驱逐它,标记是 1 就清掉标记、指针往下走,等于再给它一次机会。1969 年 Corbató 最早描述了这套办法²。脏页还要多算一笔账:驱逐之前得先写回磁盘,干净的文件页直接丢掉就行,下次用再从文件里读回来。

Linux 走的也是这条近似路线³:页分活跃与不活跃两档,刚进来先放不活跃档,再被碰到才升到活跃档,回收先从不活跃档的尾巴上挑。没有文件 backing 的匿名页,无处可回,只能写进交换区;干净的文件页,丢掉也不丢数据。后台的 kswapd 在空闲页低于水位时就开始回收,实在来不及,申请内存的进程自己动手回收,叫直接回收。swappiness 这个旋钮,调的是回收时偏向匿名页还是文件页。回收不是扫地出门,是给下一页留白。

二、记忆的扔法,按热度扔

如果 AI 的操作系统先出现,扔东西的账本也要重写。智能体的上下文就是它手头的工作集,窗口一满,新信息进来之前,也得先决定扔哪一段:最早的对话、摘要过的旧事、还是某个工具的返回结果。PagedAttention 把分页的笔法用进了大模型 KV cache⁴:逻辑上连续的序列,物理上切成块,块可以共享、可以按需分配,驱逐与复用那套账,在显存里重算了一遍。MemGPT 更进一步,把上下文窗口当主存、外部存储当磁盘,摘要换入换出就是换页⁵。

再推一格:未来的扔法,依据不该只是“多久没用”。一页内存被驱逐,代价是重读一次;一段摘要被驱逐,代价可能是永远找不回的细节。扔之前要多算两笔:这段东西以后还会不会被想起,丢了之后重建要花多少钱。按热度扔,按重建代价扔,按预测的下一步扔,三笔账合在一起,才是智能体时代的时钟算法。范式之眼也在这里:线性地址的驱逐问的是“这页的标记是 0 还是 1”,向量空间的驱逐问的是“这段离当前意图有多远、重建有多贵”,偏移算术失效了,驱逐的逻辑还活着。

还有一层平时看不见:被扔掉的东西,账算在谁头上?文件页丢了重读,匿名页丢了换出,摘要丢了就没了。驱逐看起来中立,代价分布并不中立,架构里先把这笔账认下来,扔的时候才不会只图省事。

三、亲手看回收在干活

手边任何一台 Linux 机器,先看两档各有多少:

grep -E '^(MemTotal|MemFree|MemAvailable|Active|Inactive|SwapTotal|SwapFree)' /proc/meminfo

Active 是最近碰过的,Inactive 是候选的回收池。再看回收到底干了多少活:

grep -E 'pgscan|pgsteal|pswp' /proc/vmstat

pgscan 是扫描过的页数,pgsteal 是真正回收到的页数,pswpin/pswpout 是进出交换区的页数。pgscan 涨得快、pgsteal 跟不上,说明系统一直在找可扔的页,却没找到多少,内存正吃紧。再看那个旋钮:

cat /proc/sys/vm/swappiness

默认 60,数字越大,回收时越偏向匿名页,越小越偏向保匿名页、多扔文件页。改它之前先想清楚:这台机器上,文件缓存和程序内存,哪个丢了更贵?

落到普遍场景,同一本账都能套。本地大模型服务上,KV cache 的块驱逐,就是显存版的时钟算法,块留得太久占显存,扔得太早重算贵;边缘小设备上,物理内存本来就小,回收池一干,系统就开始直接回收,任务先变慢再说;视频 AI 平台里,一路视频的推理缓冲也可以当成“页”来管,告警触发时才换入,平常不必全占着;企业私有智能中心里,一个智能体的上下文预算先按工作集算清,再往下排任务,摘要驱逐就不是提示词技巧,而是内存管理。

觉 然 小 注

扔的不是最旧的,是最不可能再回来的。内存如此,记忆也是:留下的标准不是来得早晚,是还会不会再被想起。

引 用 与 出 处

  1. [1] Bélády, L. A., Nelson, R. A., Shedler, G. S. An anomaly in space-time characteristics of certain programs running in a paging machine. Communications of the ACM, 1969.
  2. [2] Page replacement algorithm. Wikipedia. https://en.wikipedia.org/wiki/Page_replacement_algorithm
  3. [3] Robert Love. Linux Kernel Development. Addison-Wesley, 2010.
  4. [4] Kwon, W. et al. Efficient Memory Management for Large Language Model Serving with PagedAttention. SOSP, 2023. https://arxiv.org/abs/2309.06180
  5. [5] Packer, C. et al. MemGPT: Towards LLMs as Operating Systems. arXiv:2310.08560, 2023. https://arxiv.org/abs/2310.08560

· · ·

← 返回资讯中心