文章

操作系统学习笔记 | 5. 虚拟内存

虚拟内存的起因——内存空间不足

随着程序规模的增长,其对内存的需求远远超过了物理内存的发展速度。因此,我们希望能在有限的内存中运行更多程序,而不受物理内存容量的限制。

理想的存储器应当具备以下特性:

  • 更大:能够存储更多数据和程序。

  • 更快:提供更高的访问速度。

  • 更便宜:降低存储成本。

  • 非易失性:断电后数据仍然可以保存。

但实际存储器的情况如下:

  • 内存(RAM)速度快但价格昂贵,容量有限。

  • 硬盘(HDD/SSD)价格低廉但速度较慢。

因此,我们可以引入硬盘作为存储层级的一部分,在操作系统的管理下,利用硬盘的空间来扩展可用内存。

解决内存不足的方案

主要有以下三种方式:

  1. 覆盖技术(Overlay):仅将当前需要执行的部分装入内存,程序员手动管理。

  2. 交换技术(Swapping):将不活动的进程换出到硬盘,系统自动管理。

  3. 虚拟存储技术(Virtual Memory):以更小的粒度进行内存管理,由操作系统负责调度。

覆盖技术

目标:在较小的可用内存里运行较大的程序,通常用于多道程序系统,与分区存储管理配合使用。

原理

  • 把程序划分为多个独立的模块,并确保不会同时执行的模块共享同一块内存区域。

  • 常用代码和数据常驻内存,不常用部分存放在外存,需要时才加载。

  • 互不依赖的模块可以动态加载和覆盖,以节省内存。

缺点

  • 开发复杂度较高,需要程序员手动划分模块。

  • 运行时频繁从外存加载模块,导致性能下降(以时间换空间)。

交换技术

目标:多个程序共享内存资源,尽可能让更多的进程运行。

方法

  • 换出(Swap-out):把暂时不运行的进程保存到外存,释放内存空间。

  • 换入(Swap-in):当进程需要执行时,再从外存加载回内存。

示意图如下:

关键问题

  1. 交换时机:尽量减少交换次数,仅在内存不足时进行交换。

  2. 交换区域大小:必须足够大,以存储进程的完整地址空间。

  3. 地址重映射:进程换入内存后可能位于不同的地址,需要支持动态地址映射

覆盖 vs 交换

对比项

覆盖技术

交换技术

适用场景

程序内部模块

进程之间

触发方式

手动划分,程序员控制

操作系统自动管理

内存管理粒度

模块级

进程级

复杂度

需要程序员手动划分

操作系统负责,无需开发者干预

虚拟存储技术

覆盖和交换技术虽然能缓解内存不足的问题,但各自存在局限性:

  • 覆盖技术需要程序员手动管理,开发成本高。

  • 交换技术每次换入换出整个进程,开销较大。

目标

  • 无需手动划分,由操作系统自动管理。

  • 只加载当前需要的部分,减少内存占用。

  • 支持进程部分换入换出,减少交换开销。

核心思想——程序的局部性原理 程序在执行过程中,访问的指令和数据往往局限在一定范围内,称为局部性原理

  • 时间局部性(Temporal Locality):近期访问过的数据很可能在短时间内再次被访问。

  • 空间局部性(Spatial Locality):一次访问的数据附近的内容很可能也会被访问。

示例代码对比:

// 写法 1(列优先访问)
for(int j = 0; j < 1024; j++){
    for(int i = 0; i < 1024; i++){
        A[i][j] = 0;
    }
}
​
// 写法 2(行优先访问)
for(int i = 0; i < 1024; i++){
    for(int j = 0; j < 1024; j++){
        A[i][j] = 0;
    }
}

分析

  • 写法 1 会导致 1024 × 1024 次缓存未命中(Cache Miss),因为每次访问的新列数据可能导致缺页。

  • 写法 2 只会发生 1024 次缓存未命中,因为数据按行存储,能充分利用缓存。

虚拟页式内存管理

关键点

  1. 请求分页:按需加载页面,减少内存占用。

  2. 页面置换:当内存不足时,选择替换某些页面。

页表项结构

  • 驻留位:表示该页是否在内存中。

  • 保护位:标识可读、可写、可执行权限。

  • 修改位:记录该页是否被修改过,决定是否需要回写外存。

  • 访问位:记录该页最近是否被访问,辅助页面置换策略。

缺页中断处理流程

  1. 检查是否有空闲页帧,有则直接分配,否则执行页面置换。

  2. 如果需要替换某个页面,先检查该页是否被修改过,如果是,则将其写回外存。

  3. 将新页面从外存读取到内存中。

  4. 更新页表,设置驻留位,并更新物理页帧号。

  5. 重新执行被中断的指令。

虚拟内存性能

有效存储器访问时间(EAT)

EAT = TLB 查找时间 + (1 - TLB 命中率) × 页表查找时间 + 缺页率 × 缺页处理时间

影响因素:

  • TLB(快表):提高页表查找速度,减少内存访问延迟。

  • 页面置换策略:如 LRU(最近最少使用)等,减少缺页率。

  • 预取策略:提前加载可能访问的页面,提高性能。

  • 过度换页(Thrashing):如果缺页率过高,系统可能陷入不断换页的低效状态。


总结

  • 虚拟内存通过分页管理,实现按需加载,减少内存占用。

  • 操作系统通过TLB 加速地址映射,降低访存开销。

  • 局部性原理是提高性能的关键,应尽量优化数据访问模式。

  • 合理的页面置换策略能减少缺页,提高系统响应速度。

License:  CC BY 4.0