操作系统中的 CPU 和主内存(Main memory)都是稀缺资源,所有运行在当前操作系统的进程会共享系统中的 CPU 和内存资源,操作系统会使用 CPU 调度器分配 CPU 时间[^1]并引入虚拟内存系统以管理物理内存,本文会分析操作系统为什么需要虚拟内存。
在回答虚拟内存存在的必要性之前,我们需要理解操作系统中的虚拟内存是什么,它在操作系统中起到什么样的作用。正如软件工程中的其他抽象,虚拟内存是操作系统物理内存和进程之间的中间层,它为进程隐藏了物理内存这一概念,为进程提供了更加简洁和易用的接口以及更加复杂的功能。
如果需要我们从头设计一个操作系统,让系统中的进程直接访问主内存中的物理地址应该是非常自然的决定,早期的操作系统确实也都是这么实现的,进程会使用目标内存的物理地址(Physical Address)直接访问内存中的内容,然而现代的操作系统都引入了虚拟内存,进程持有的虚拟地址(Virtual Address)会经过内存管理单元(Memory Mangament Unit)的转换变成物理地址[^2],然后再通过物理地址访问内存:
主存储是相对比较稀缺的资源,虽然顺序读取只比磁盘快 1 个数量级,但是它能提供极快的随机访问速度,从内存上随机读取数据是磁盘的 100,000 倍[^3],充分利用内存的随机访问速度是改善程序执行效率的有效方式。
操作系统以页为单位管理内存,当进程发现需要访问的数据不在内存时,操作系统可能会将数据以页的方式加载到内存中,这个过程是由上图中的内存管理单元(MMU)完成的。操作系统的虚拟内存作为一个抽象层,起到了以下三个非常关键的作用:
- 虚拟内存可以利用磁盘起到缓存的作用,提高进程访问指定内存的速度;
- 虚拟内存可以为进程提供独立的内存空间,简化程序的链接、加载过程并通过动态库共享内存;
- 虚拟内存可以控制进程对物理内存的访问,隔离不同进程的访问权限,提高系统的安全性;
缓存
我们可以将虚拟内存看作是在磁盘上一片空间,当这片空间中的一部分访问比较频繁时,该部分数据会以页为单位被缓存到主存中以加速 CPU 访问数据的性能,虚拟内存利用空间较大的磁盘存储作为『内存』并使用主存储缓存进行加速,让上层认为操作系统的内存很大而且很快,然而区域很大的磁盘并不快,而很快的内存也并不大。