1、进程的虚拟地址空间
每个进程都有自己的虚拟地址空间。对于32位的进程,这个地址空间的大小是4GB,这是因为32位的指针可以表示从0x00000000到0xFFFFFFFF之间的任一值。对于64位的,地址空间大小为16TB。
因为每个进程都有自己专有的地址空间,当进程中的个线程运行时,它们只能访问属于该进程的内存。线程即看不到属于其他线程的内存,也无法访问它们。
在Windows中,正在运行的线程看不到属于操作系统本身的内存,这意味着他不能无意间访问到操作系统的数据。
虚拟地址空间不是物理存储器。还需要把物理存储器分配或者映射到相应的地址空间,否则将导致访问违规(access voilation)
2、虚拟地址空间的分区
2.1、空指针赋值空间
这一分区是进程地址空间中从0x00000000到0x0000FFFF的闭区间,保留该分区的目的是为了帮助程序员捕获对空指针的赋值。
如果进程中的线程试图读取或者写入位于这一分区内的内存地址,就会引发访问违规。
没有任何办法可以让我们分配到位于这一地址空间内的虚拟内存,即使是使用Win32应用程序编程接口API也不例外。
2.2、用户模式分区
在windows中,所有exe和dll都载入到这一区域,每个进程都有可能将这些dll载入到这一分区内的不同地址(虽然这种可能性很小),系统同时会把该进程可以访问的所有内存映射文件映射到这一分区。
1、在x86 Windows下得到更大的用户模式分区
x86版的windows提供了一种模式来增大用户模式分区,最多不超过3GB。需要对windows中的启动配置数据(boot configuration data 简称BCD)进行设定,并重新启动机器。有关BCD的更多信息,请查阅:http://www.microsoft.com/whdc/system/platform/firmware/bcd.mspx
当系统即将运行一个应用程序时,它会检查应用程序在链接时是否使用了/LARGEADDRESSAWARE链接器开关。如果是,则相当于应用程序在声明它会充分利用大用户模式地址空间,而不会对内存地址进行任何不当的操作。反之,如果应用程序在链接时没用使用/LARGEADDRESSAWARE开关,那么操作系统会保留用户模式分区中2GB以上到内核模式开始处的整个部分。这样,由于所有分配到的内存地址的最高位都是0,因此避免了应用程序对该位做出错误的解释。
2、在64位Windows下得到2GB用户模式分区
为了能让32位程序在64位系统下运行,系统使用地址空间沙箱(address space sandbox),即进程地址空间被限制在最底部的2GB中,相当于把一个高33位都为0的64位地址截断为32位地址。
在默认情况下, 当运行一个64位应用程序时,系统会保留用户模式地址空间中位于地址0x0000000080000000之后的所有部分,这就确保了所有内存都分配自64位地址空间中的最底部的2GB。为了让64位应用程序能够访问整个用户模式分区,必须用/LARGEADDRESSAWARE链接器开关来链接应用程序。
操作系统会在创建进程的64位地址空间时检查可执行文件的/LARGEADDRESSAWAR标志,对DLL来说,系统会忽略该标志,所有DLL必须经过正确编写,以便能够在4TB用户模式分区的情况下正常运行,否则其结果将不可预料。
3、内核模式分区
这一分区是操作系统代码的驻地。与线程调度。内存管理、文件系统支持、网络支持以及设备驱动程序相关的代码都载入到该部分。
3、地址空间中的区域
4、给区域调拨物理存储器
5、物理存储器和页交换文件
![](https://img-my.csdn.net/uploads/201303/14/1363272366_1115.jpg)
6、页面保护属性
![](https://img-my.csdn.net/uploads/201303/14/1363272453_2232.jpg)