虽然可以寻址4GB的内存,而在PC里往往没有如此多的真实物理内存。操作系统和硬件(这里指的是CPU中的内存管理单元MMU)为使用者提供了虚拟内存的概念。Windows的所有程序(包括Ring0层和Ring3层的程序)可以操作的都是虚拟内存。之所以称为虚拟内存,是因为对它的所有操作,最终会变成一系列对真实物理内存的操作。
在这里,简单的介绍下转换的过程,有助于我们更进一步理解windows的内存管理。在CPU中有一个重要的寄存器CR0,它是32位的寄存器,其中的一个位(PG位)是负责告诉系统是否分页的。Windows在启动前会将它的PG位置1,即Windows允许分页。DDK中有个宏PAGE_SIZE记录着分页大小,一般为4KB。4GB的虚拟内存会被分割成1M个(4GB/4KB = 2的20次方)分页单元。
其中有一部分单元会和物理内存对应起来,即虚拟内存中第N个分页单元对应着物理内存第M个分页单元。这种对应不是一一对应,而是多对一的映射,多个虚拟内存页可以映射同一个物理内存页。还有一部分单元会被映射成磁盘上的文件,并标记为脏的(Dirty)。读取这段虚拟内存的时候,系统会发出一个异常,此时会触发异常处理函数,异常处理函数会将这个页的磁盘文件读入内存,并将标记设置为不脏。当让经常不读写的内存页,可以交换(Swap)成文件,并将此页设置为脏。还有一部分单元什么也没对应,即空的。
上述过程简化成图1,。从图1中可以看出,进程1和进程2虚拟内存映射的方式完全相同,有的物理内存块只映射到进程1上,因此无论对进程2怎样操作,也不会影响到那块内存。另外有些物理内存既映射到进程1上,也映射到进程2上。这样修改进程2的那段虚拟内存,进程1的相应的虚拟内存也会随之改变。这种方法就是所谓的进程间共享内存。当然,这些都是严格控制在Windows操作系统之下的。大部分的虚拟内存是没有被映射到物理内存上的。
Windows之所以如此设计,是基于以下两个原因:
* 第一是虚拟的增加了内存的大小。不管PC是否有足够的4GB的物理内存,操作系统总会有4GB的虚拟内存。这就允许使用者申请更多的内存,当物理内存不够的时候,可以通过将不常用的虚拟内存页交换成文件,等需要的时候再去读取。
* 第二是使不同进程的虚拟内存互不干扰,为了让系统可以同时运行不同的进程,Windows操作系统让每个进程看到的虚拟内存都不同。这个方法就使不同的进程会有不同的物理内存到虚拟内存的映射。例如进程A和进程B的内存地址0x40000会完全不同。修改A进程这个地址,不会影响到进程B。因为A进程的这个地址可能映射的是一段物理内存地址,而B的这个地址映射的是另外一段物理内存地址。