进程的虚拟地址空间
WIndows为每个32位进程分配了4GB的虚拟地址空间。每个进程都认为自己拥有4GB的内存空间, 4GB的大小是因为:32位 CPU可以取地址的空间为2的32次方,就是4GB大小。
而64位进程, CPU可以取地址的空间为2的64次方,所以64位进程的虚拟地址空间大小为16EB。
进程的隔离
每个进程都有自己专用的地址空间,就是这个虚拟地址空间。进程中的线程只能访问它所在的进程的内存。线程是看不到其他进程的内存的,也无法访问它们。
系统为了隔离进程,使得每个进程只能访问进程自己申请的内存,而不能访问其他进程的内存。操作系统对每个进程的内存使用线性地址编制,通过内存的分页机制,在进程需要访问物理内存时,通过进程的页表找到实际物理内存的地址,通过系统读写内存中的数据。
当我们在Windows中双击一个应用程序图标后,操作系统创建该应用程序的一个进程,Windows使得每个进程都拥有2GB的地址空间,这2GB地址空间用于程序存放代码、数据、堆栈、自由存储区(堆),另外2GB用于共享系统使用。
这些地址是该进程空间中的虚拟地址,并不是物理内存中的地址。虚拟地址空间,只是Windows为该进程分配的,一个虚拟的地址空间,只有转换为物理内存关联后才有意义 。
虚拟地址空间分区
应用程序虽然有这么大的地址空间可用,但是这只是虚拟地址空间,不是物理存储器。这个地址空间只不过是一个内存的地址区间。
每个进程的虚拟地址空间又被划分为许多个分区(partion)。
由于地址空间的分区,依赖于操作系统的底层实现。因此会随着Windows内核的不同而略有变化。
32位Winows内核和64位Windows内核的分区基本一致,唯一的不同在于分区的大小和分区的位置。
内核模式分区 2G 高地址。 系统运行的空间,所有进程共用的,用户模式的的代码不能访问这部分代码,若要访问,需要通过系统提供的API进入到内核态。 |
64KB 禁入分区 64K 用来分隔内核模式跟用户模式的 |
用户模式分区 2G 应用程序可以访问 ,用户代码在这里跑,堆栈都在这里,用户可以随便用,一般出错都在这里。 |
空指针赋值分区 64K 0x00000000到0x0000FFFF ,用来给空指针赋值的,这个分区不可操作,操作就报错。 |
- 空指针赋值分区:用来给空指针赋值的,这个分区不可操作,操作就报错。
- 用户模式分区:用户代码在这里跑,堆栈都在这里,用户可以随便用,一般出错都在这里。
- 64kb禁入分区:就是为了分隔内核模式跟用户模式的。
- 内核模式分区:系统运行的空间,所有进程共用的,用户模式的的代码不能访问这部分代码,若要访问,需要通过系统提供的API进入到内核态。
空指针赋值分区
空指针赋值分区是进程地址空间中,从0x00000000到0x0000FFFF的闭区间