跳到主要内容

虚拟内存

虚拟内存让每个进程都"独占"一个巨大的、私有的、连续的地址空间,实际物理内存则由 OS 统一调度、按需分配。它是分页机制的自然延伸,同时把主存与磁盘统一成两级存储层次。

虚拟地址到物理地址

CPU 发出的地址是虚拟地址,MMU 负责查页表得到物理页帧号,再拼上偏移得到物理地址。若页表项的Present位为 0,意味着该页不在内存,触发缺页异常由内核处理。

CR3 -> PDPT -> PD -> PT -> PFN
VA[47:39] VA[38:30] VA[29:21] VA[20:12] VA[11:0]
拼成 PA[47:12] + offset

权限位(R/W/U)与访问位(A)、脏位(D)在转换过程中由硬件同步维护,供换页决策使用。

TLB 加速

页表在内存中,每次访存都先查内存中的页表会拖慢 CPU。MMU 内置一块全相联高速缓存——TLB(Translation Lookaside Buffer),缓存最近用过的页表项。命中时一次转换可在一个时钟周期完成;未命中才走多级页表并回填 TLB。

TLB 容量小(几十到几百项),context switch 时通常用 ASID(Address Space ID)区分不同进程,避免全部失效。

缺页处理流程

  1. 进程访问未在内存的页,MMU 触发缺页中断。
  2. 内核根据缺页地址与触发原因判断是合法访问还是越界。
  3. 合法访问则选择一个物理页帧(若无可用,先按置换算法淘汰一页)。
  4. 若被淘汰页脏,先写回磁盘(write-back),然后从磁盘调入新页。
  5. 更新页表项并刷新对应 TLB,恢复进程执行。

整个过程对进程透明,像访问"连续大内存"一样编程。

页面置换算法

当物理页耗尽,必须把已有页面换出:

  • FIFO:按进入内存的顺序淘汰,实现最简单,但可能淘汰热点页(Belady 异常)。
  • LRU(Least Recently Used):淘汰最久未使用,理论最优,实现成本高,常用近似。
  • Clock(二次机会):把页框组织成环形链表,使用位为 0 时淘汰,否则清位后跳过。是 LRU 的高效近似,Linux 实际算法更复杂(基于 refault distance)。
算法实现复杂度命中率表现
FIFO极低一般,且有 Belady 异常
LRU
Clock接近 LRU

抖动与工作集

**抖动(thrashing)**指系统频繁换页、磁盘 IO 飙升而有效计算极少的状态,常因多道程序度过高引起。工作集(Working Set)模型定义为进程在最近 Δ 时间内实际访问的页面集合,OS 据此动态调整多道程度:当所有进程的工作集之和超过物理内存,主动挂起部分进程,直至可运行集的工作集能装下。

工程上,Linux 用 kswapd 后台回收、readahead 预读、内存压缩与 zswap 等多策略协同避免抖动。