计算机系统中的RAM资源有限,由系统上运行的进行竞争共享。当系统运行的多个应用程序时,所有进程分配的内存总量会超过系统上RAM的数量,这是很常见的一种情况。
操作系统支持虚拟内存,这样进程就可以分配和使用比系统上安装的RAM数量还要多的内存。也就是说,进程的空间地址不受物理RAM数量的限制。有了虚拟内存,操作系统便可以使用次级存储器(如硬盘)上的后备存储空间,保存无法放到RAM中的进程的地址空间。然而,CPU仍然只能访问RAM中的地址,因此,操作系统必须在磁盘后备存储空间和RAM之间交换数据,以便能够在进程运行时访问内存。
在特定的时刻,进程可能只是需要使用分配的总内存的小部分,我们称之为进程的工作集。只要操作系统将这一工作保存到RAM中,就可以忽略虚拟内存对执行速度的影响。工作集是一个动态实体,根据进程运行时当前使用的数据而变化。
如果进程访问RAM外部的内存地址,则需要从硬盘的后备存储中读取对应的数据,放到RAM中。如果当前没有空闲的RAM用户数据载入,就需要预先将RAM中现存的一些数据换出并保存到磁盘,释放物理RAM。
虚拟内存由操作系统处理。用户进程并不参与这一过程的实现。他不用关心地址空间是否在RAM中,也不用关心访问的数据是否转移到了主存中。
使用虚拟内存的后果是,进程使用的地址与物理RAM的地址并不对应。只要想一想进程地址空间比RAM大,你就明白了。因此,需要将进程读写的地址从进程的虚拟地址空间转换成物理的RAM地址。由于访问每个内存都要进行地址的转换,为了减少对执行速度的影响,这些工作全都是CPU执行的。
操作系统一般使用一种称为“分页”的方案,来实现虚拟地址到物理地址的转换。使用分页内存方案时,物理内存被划分伟固定长度的块,称为(^-^)页帧。大多数操作系统,包括mac OS 和 iOS,使用的帧长度均为4096字节。类似的,每个进程的虚拟地址空间也都可以被划分为固定长度的块,称之为页。每页的字节数与每帧的字节数始终相同。这样便可以将进程中的每页映射到物理内存中的一个帧里。
虚拟内存的另一个优点是,进程虚拟地址空间中页码连续的缓冲区,可以分布到物理内存中多个不连续的帧里。这就解决了物理内存的碎片问题,因为一个进程分配的内存可以分布到多个物理内存段,