在早年的计算机中,地址的转换很单纯,有效地址就直接等于物理存储器的地址,这适合同一时间只有一个进程在运作。但Windows不会只有一个Window,多进程并存是现代计算机的基本情形。后来人们决定为每个进程划定一块专用内存区域,这样可以让多个进程同时运作。但这种分段方式会让内存在进程开开关关的过程中产生很多碎片,很多小块内存无法被利用。由于内存空间总是相对有限的,因此应用程序也不能疯狂的将所有东西直接塞进内存当中。同时我们也不能依赖硬盘这个缓慢的二级存储器去充当内存,那实在太慢了。为了调和这个矛盾,操作系统都引入了虚拟内存机制。
Windows的虚拟内存并非简单的指位于我们硬盘上的那个pagefile.sys文件,或者是在内存装不下的时候用于应急的“模拟内存”。在当代Windows系统中,任何一个进程都会被赋予其自己的虚拟地址空间,这是一种逻辑地址空间,并不存在实体,该虚拟地址空间可以覆盖了一个相当大的范围。对于一个32位进程,其可以拥有的虚拟地址空间为2^32=4GB,典型情况为2GB用户空间,2GB系统内核空间(最大可调整为3GB用户空间和1GB内核空间),这与安装了多少物理内存没有任何关系。每个进程的虚拟地址空间都会被标上各自的ID,这样两个进程之间的虚拟地址就不会互相干扰。虽然每一个32位进程可使用4GB的地址空间,但并不意味着每一个进程实际拥有4GB的物理地址空间或使用4GB物理内存,虚拟地址仅仅是一种逻辑地址。
应用程序自然不能总在看不见摸不着的虚拟地址里溜达,最终还是需要实实在在的物理存储器关联。应用程序会去为其虚拟地址申请物理存储空间,这个空间通常会小于应用程序的总虚拟空间。这里所说的物理存储器并不局限于计算机内存,还包括在磁盘空间上创建的页文件(pagefile.sys),其存储空间大小为计算机内存和页文件存储容量之和(所以Windows自动管理时的pagefile.sys是很大的)。由于通常情况下磁盘存储空间要远大于内存的存储空间,因此页文件的使用对于应用程序而言确实相当于透明的增加了其所能使用的内存容量,只是速度慢了点。有了虚拟内存的存在,程序本身就不用完全装入内存,或者完全存于硬盘,系统会将目前需要的部分读入内存处理,暂时不需要的就放在硬盘的页文件留作交换。不过CPU并不能直接去访问磁盘上的信息,每次磁盘访问都必须通过内存,所以若所需的内容在磁盘上的页文件中,就需要先加载到内存然后访问。
应用程序本身并不关心自己占用的内存大小,它只要求提交物理存储器,无论是磁盘还是内存。那么自然是尽量分配更多的高速的内存作为物理存储器最佳,所以我们也知道内存大的机器在大量应用程序启动时会快。当一个进程的虚拟内存提交的物理存储器是物理内存时,我们就可以省去从磁盘的页文件加载数据到物理内存的时间,程序的工作效率自然就会提高。尽管我们的内存超出了32bit系统的地址结构范围,但我们只要将4GB地址以上的物理内存为虚拟内存所用就不会浪费内存了。