Windows核心编程:内存体系结构

作者:shenzi

链接:http://blog.csdn.net/shenzi

Windows核心编程:内存体系结构

1.进程的虚拟地址空间
    每 个进程都有自己的虚拟地址空间。对32位进程来说,这个地址空间的大小为4GB,这是因为32位指针可以表示从0x00000000到 0xFFFFFFFF之间的任一值,指针在这个范围内可以有4 294 967 296个值,它们覆盖了进城的4GB地址空间。对62位进程来说,它们可以覆盖16EB地址空间,这个地址空间实在太大了!!!
     每个进程有自己的私有地址空间,但是要记住这只是虚拟地址空间,不是物理存储器。为了能过正常读/写数据,我们需要把物理存储器分配或映射到相应的虚拟地址空间,否则将导致访问违规。
2.虚拟地址空间的分区

    每个进程的虚拟地址空间被划分成许多分区(partition)。由于地址空间的分区依赖于操作系统的底层实现,因此会随着Windows内核的不同而略有变化。表1列出了各平台上对进程地址空间的分区。

表1:进程地址空间是如何划分的

分区

x 86 32位Windows

3 GB用户模式下的 x 86

32位Windows

x 64 64位Windows

IA-64 64位 Windows

空指针赋值分区

0x00000000

0x00000000

0x00000000'00000000

0x00000000'00000000

0x0000FFFF

0x0000FFFF

0x00000000'0000FFFF

0x00000000'0000FFFF

用户模式分区

0x00010000

0x00010000

0x00000000'00010000

0x00000000'00010000

0x7FFEFFFF

0xBFFEFFFF

0x000007FF'FFFEFFFF

0x000006FB'FFFEFFFF

64-KB

禁入分区

0x7FFF0000

0xBFFF0000

0x000007FF'FFFF0000

0x000006FB'FFFF0000

0x7FFFFFFF

0xBFFFFFFF

0x000007FF'FFFFFFFF

0x000006FB'FFFFFFFF

内核模式分区


0x80000000

0xC0000000

0x00000800'00000000

0x000006FC'00000000

0xFFFFFFFF

0xFFFFFFFF

0xFFFFFFFF'FFFFFFFF

  0xFFFFFFFF'FFFFFFFF

空指针赋值分区:
    保留该区域的目的是为了帮助程序员捕获对空指针的赋值。如果进程中的线程试图读取或写入位于这一分区内的内存地址,就会引发访问违规。没有任何办法可以让我们分配到位于这一地址区间内的虚拟内存。
用户模式分区:
    这一分区是进程地址空间的驻地。对所有应用程序来说,进程的大部分数据都保存在这一分区。
内核模式分区:
    系 统需要用这一空间来存放内核代码。设备驱动程序代码、设备输入/输出高速缓存、非分页缓冲池分配表、进程页面表,等等。驻留在这一分区内的任何东西为所有 进程共有。该分区中的所有代码和数据都被完全的保护起来。如果一个应用程序试图读取或写入位于这一分区中的内存地址,会引发访问违规。在默认情况下,访问 违规会导致系统先向用户显示一个消息框,然后结束该应用程序。
3.地址空间中的区域
    当系统创建一个进程并赋予它地址空间时,可用地址空间中的大部分都是闲置的(free)或尚未分配的(unallocated)
为了使用这部分地址空间,我们必须调用VirtualAlloc来分配其中的区域(region)分配区域的操作被称为预定(reserving)
    当应用程序预定地址空间区域时,系统会确保区域的起始地址正好是分配粒度 (allocation granularity)的整数倍。分配粒度会根据不同的CPU平台而有所不同。目前,所有的CPU平台都使用相同的分配粒度,大小为64KB—也就是系统会把分配请求取整到64KB的整数倍。
     当应用程序预定地址空间的一块区域时,系统会确保区域的起始地址正好是系统页面 大小的整数倍。页面是一个内存单元,系统通过它来管理内存。与分配粒度相似,页面大小会根据不同的CPU而有所不同。x86和x64系统使用的页面大小为4KB,IA-64系统使用的页面大小为8KB。
     (即当我们预定地址空间时,分配粒度影响我们的起始地址,因为起始地址必须整除分配粒度。页面大小影响我们预定的大小,大于等于我们预定的大小,因为要是页面大小的整数倍。)
    虽然系统规定应用程序在预定地址空间区域时起始地址必须是分配粒度的整数倍,但系统自己却不存在这样的限制。非常有可能出现的情况是,系统预定的区域的起始地址并非64KB的整数倍,但是预定的区域仍然必须是CPU页面大小的整数倍。
    当程序不再需要访问所预定的地址空间区域时,应该释放该区域。通过调用VirtualFree函数来完成。
4.给区域调拨物理存储器
    
为了使用所预定的地址空间区域,我们还必须分配物理存储器,并将存储器映射到所预定的区域。这个过程称为调拨(committing)物理存储器。物理存储器始终都以页面为单位来调拨。我们通过调用VirtualAlloc函数来讲物理存储器调拨给所预定的区域。
     当程序不再需要访问所预定区域中已调拨的物理存储器时,应该释放物理存储器。这个过程称为撤销调拨(decommitting)物理存储器,通过调用VirtualFree函数来完成。
    (
VirtualAlloc, VirtualFree具体使用在以后章节具体讨论
     说明:预定只是在虚拟地址空间中预定区域,这时并未为该区域指定物理地址空间。通过调拨操作,我们将之前预定的虚拟地址空间绑定到特定的物理地址空间。
5、物理存储器和页交换文件   
     在老式的操作系统中,物理存储器被认为是极其中的内存的总量。当今的操作系统能让磁盘空间看起来像内存一样。磁盘上的文件一般被称为页交换文件 (paging file),其中包含虚拟内存,可供任何进程使用。
     为了能够使用虚拟内存,操作系统需要CPU的大力协助。当线程试图访问存储器中的一个字节时,CPU必须知道该字节是在内存中还是在磁盘上。如果一台机器 准备了1GB的内存,硬盘上还有1GB的也交换文件,那么有用程序会认为可用内存的总量为2GB。当然,这台机器实际上并没有准备2GB的内存。实际上, 是操作系统与CPU分工协作,把内存中的一部分保存到也交换文件中,并在应用程序需要的时候再将页交换文件中的对应部分载入内存。因此,使用也交换文件可 以增大应用程序可用内存的总量。最好把物理存储器看成是保存在磁盘上的也交换文件中的数据。
     当一个线程试图访问所属进程的地址空间中的一块数据时,有可能会出现两种情况。图1显示了经简化后的流程:
    

图1:把虚拟地址转换为物理存储器地址

     系统需要在内存和也交换文件之间复制页面的频率越高,硬盘颠簸(thrash)得越厉害,系统运行得也越慢。
     要让计算机跑的快,最好是增加内存。
不在页交换文件 中维护的物理存储器:
    
如 果每次运行一个程序时,系统都必须为该进程的代码和数据预定地址空间区域,为这些区域调拨物理存储器,然后把硬盘上的程序文件中的代码和数据复制到页交换 文件中已调拨的物理存储器中去。那么载入一个程序并让它运行起来会花费很长的时间。事实上,系统并不会执行刚才所说的这些操作。当用户要求执行一个应用程序时,系统会打开该应用程序对应的.exe文件并计算出应用程序的代码和数据的大小。然后系统会预定一块地址空间,并注明与该区域相关联的物理存储器就是.exe文件本身。 是的,系统并没有从页交换文件中分配空间,而是将.exe文件的实际内容用作程序预定的地址空间区域。这样一来,不但载入程序非常快,而且页交换文件也可以保持一个合理的大小。
    
当把一个程序位于磁盘上的文件映像(即一个.exe或DLL文件)用作地址空间区域对应的物理存储器时,我们称这个文件映像为内存映像文件 (memory mapped file)。当载入一个.exe或DLL时,系统会自动预定地址空间区域并把文件映像映射到该区域。
6.页面保护属性
    
我们可以给每个已分配的物理存储页指定不同的页面保护属性。表2列出了所有页面保护属性:

表2:内存页面保护属性
保护属性

 

描述

 

PAGE_NOACCESS

试图读取页面、写入页面或执行页面中的代码将引发访问违规。

PAGE_READONLY

试图写入页面或执行页面中的代码将引发访问违规。

PAGE_READWRITE

试图执行页面中的代码将引发访问违规。

PAGE_EXECUTE

试图读取页面或写入页面将引发访问违规。

PAGE_EXECUTE_READ

试图写入页面将引发访问违规。

PAGE_EXECUTE_READWRITE <

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值