为什么要有虚拟内存?
重要内容
虚拟内存是一种重要的内存管理技术
- 扩展可用内存:物理内存的容量有限,而程序可能需要比物理内存更多的内存。虚拟内存通过使用硬盘上的一部分空间(通常称为交换空间或页面文件)作为扩展的内存,使得程序能够使用远超物理内存的内存
- 程序隔离与安全:每个程序都运行在自己的虚拟内存空间中,彼此之间不会直接影响。即使不同程序共享相同的物理内存,每个程序也只能访问它自己的虚拟地址空间
- 简化内存管理:虚拟内存使得程序员不必关心物理内存的分配和管理。程序可以在一个大、连续的虚拟内存空间中运行,而操作系统负责将这些虚拟地址映射到物理内存上的实际位置
- 内存共享与优化:虚拟内存也使得多个进程能够共享某些内存区域。例如,多个进程可以共享操作系统的内核代码或某些共享库
扩展内容
虚拟内存执行原理
虚拟内存的核心思想是将程序访问的虚拟地址与物理内存中的实际地址进行映射(操作系统通过 页表 来管理这种映射关系,通过内存管理单元 MMU 来负责执行这种映射的硬件组件)
1、地址划分
虚拟地址被划分为两个主要部分,分别是 虚拟页号和 页内偏移量
- 虚拟页号:标识虚拟地址中的哪一页
- 页内偏移量:指明在该页内的具体位置
在 x86-64 架构下,虚拟地址通常是 64 位,这些位会被拆解为多个层级的页表索引和偏移量。举个例子,假设使用 4 级页表,那么虚拟地址会被分为多个部分,每一部分用于索引页表中的某个层级
2、页表映射
每个进程都有独立的页表,用于存储虚拟页号到物理页帧号的映射。页表项不仅保存物理页帧号,还有三个标志位
- 有效位:表示该映射是否有效
- 修改位:表示该页面是否被修改过
- 权限位(读/写/执行) :表示该页面的访问权限(是否允许读、写、执行等)
直接访问页表会导致性能瓶颈,因此引入 TLB:TLB 是一种硬件缓存,用于存储最近访问的页表项。TLB 可以加速虚拟地址到物理地址的转换,减少访问内存时的延迟
3、按需分页
在按需分页机制下,操作系统并不会一次性将所有进程需要的页面都加载到物理内存中。只有当进程访问某个页面时,如果进程访问一个尚未加载到物理内存的页面,操作系统会触发缺页中断,然后从磁盘加载该页面,并更新页表。缺页中断会使操作系统暂时中断进程的执行,加载所需页面,更新映射后恢复执行
如果从磁盘加载到该页面的时候,该物理内存已满,则会触发页面置换机制
页面置换机制
当物理内存满时,操作系统需要选择一些页面从物理内存中“换出”到硬盘,以腾出空间来加载新的页面
常见的页面置换算法包括
- 最近最少使用:选择最近最少使用的页面进行换出
- 先进先出:选择最早加载到内存的页面进行换出
- 最不常使用:选择最少被访问的页面进行换出
示例
假设某进程访问虚拟地址 0x12345678,这个虚拟地址需要通过页表查找相应的物理地址
- 地址拆解:虚拟地址
0x12345678将会被拆解 虚拟页号:0x12345和 页内偏移量:0x678 - 查找页表:操作系统查找该虚拟页号
0x12345对应的页表项。假设页表中该虚拟页号的映射的值是0xABCD(也就是对应的物理页帧号) - 计算物理地址:将页表中的物理页帧号
0xABCD与页内偏移量0x678拼接起来,得到物理地址为0xABCD678
4、页错误
当程序访问的虚拟页不在物理内存中时,发生 页错误。操作系统会触发 页错误处理
- 检测到页错误,操作系统暂停当前进程
- 查找是否有该虚拟页的备份(通常在硬盘的交换空间中)
- 将该虚拟页从硬盘加载到物理内存中
- 更新页表,将虚拟页映射到新的物理页框
- 恢复进程执行,继续访问该虚拟页
对比置换算法
| 算法 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 最近最少使用 LRU | 淘汰最久未使用的页面 | 局部性好,命中率高 | 需硬件支持访问时间戳 |
| 先进先出 FIFO | 淘汰最早进入的页面 | 实现简单 | Belady现象(性能劣化) |
| 最不常使用 Clock | 近似LRU,环形扫描参考位 | 硬件开销低 | 精度较低 |