Windows核心编程(笔记11) 第十三章 Windows内存体系结构 四

第十三章 Windows内存体系结构

  1.每个进程都有自己的虚拟地址空间,32位下该空间多达4GB,64位下达到了16EB,但这只是一个内存地址区间,还需要把物理存储器分配或映射到其相应的地址空间。其映射关系表现为,该虚拟地址空间上的某些区间被映射,可以是内存,可以是页交换文件,也可以是硬盘上的数据镜像等。

  2.注意:正在运行的线程看不到属于操作系统本身的内存,所以它不能无意间访问到操作系统的数据。

  3.每个进程的虚拟地址空间被划分为许多分区:(32位和64位系统的分区基本一致,只有大小和位置不同)

    ①.空指针赋值分区:该分区是为了帮助程序员捕获对空指针的赋值,试图读写此区域则访问违规。注:无任何办法让我们分配到位于这一地址区间内的虚拟内存。

    ②.用户模式分区:该分区是进程地址空间的驻地。其可用地址区间和分区大小取决于CPU体系结构(x86,x86/3GB,x64,IA-64等)。这一分区在进程间是不能互相访问的。系统会把该进程可以访问的所有内存映射文件映射到这一分区。注:1.可以通过BCDEdit /set IncreaseUserVa 3072(1024 * 3) 来将用户模式分区扩大到3GB,这样可使其可寻址地址增大,有助于提高程序的性能和可伸缩性。但是对于.exe而言,要运行在该环境下需指定链接器开关 /LARGEADDRESSAWARE,而.dll会忽略此开关,所以必须保证dll的正确编写,否则结果不可预料(怎么感觉这个3GB又蛋疼又鸡肋呢?求高人指点)。2.要让32位应用程序运行在64位系统上,为了防止因指针位数不同而导致的指针截断错误和不正确的内存访问,需让程序在地址空间沙箱中运行,确保其所有分配内存都来自于64位地址空间中最底部的2GB,这也必须用 /LARGEADDRESSAWARE来指定,同样蛋疼的,dll会忽略此标志,所以要保证dll的正确编写,否则结果不可预料(囧)。

    ③.64KB禁入分区。

    ④.内核模式分区:这是操作系统代码的驻地。与线程调度,内存管理,文件系统支持,网络支持以及设备驱动程序相关的代码都载入到该分区。该分区所有的代码和数据都是被保护起来的,任何访问都会导致访问违规。

  4.为了使用闲置或未分配的随进程创建而被赋予的地址空间,需要调用VirtualAlloc来预定其中的区域。其区域的起始地址需要保证是分配粒度(现都为64KB)的整数倍,其区域的大小必须是系统页面大小(x86和x64均为4KB,IA-64为8KB)的整数倍。当不再使用所预定的地址空间区域时,应该用VirtualFree来释放地址空间区域。

  5.要使用所预定的地址空间区域,还需要分配物理存储器,并将存储器映射到所预定的区域,即调拨物理存储器。该调拨始终都以页面为单位,同样是通过VirtualAlloc实现的,注意调拨并不需要针对整个预定区域。撤销调拨也同样用VirtualFree实现。

  6.硬盘上像内存一样使用的文件被称为页交换文件,其中包括虚拟内存可供任何进程使用。页交换文件可以增大程序可用内存的总量,但它并不是必须的,但建议使用。系统中页交换文件的大小是决定程序可用内存总量的最重要因素,相比较下,实际的内存反而对它的影响小些。注意:页交换文件和内存配合工作:将现在不需要的数据先放入页交换文件,等需要的时候再部分在入内存;最好是把物理存储器看成是保存在磁盘上的页交换文件中的数据,所以当应用程序调用VirtualAlloc来把物理存储器调拨给地址空间区域时,该空间实际上是从硬盘上的页交换文件分配得到的。

  7.当线程要访问的数据不在内存中而在页交换文件中时,则触发一次页面错误,系统随即在内存中找一块闲置页面,若无,则需释放一块已分配但没修改过的页面,若改过则需先复制到页交换文件中,这样搞定可用页面后,系统会在页交换文件中对所需访问的数据块进行定位,并并把数据载入到该可用页面,然后系统对内部表项进行更新,以反映该块数据的虚拟内存地址现在已被映射到了内存中对应的物理内存地址。这样的操作频率越高,则硬盘颠簸得越厉害,运行速度也越慢。所以大多数情况下,加大内存换来的性能提升比换个更快的CPU都要好得多。

  8.当一个程序位于硬盘上的文件映像(.exe或.dll)用作地址空间区域对应的物理存储器时,我们称这个文件映像为内存映射文件。当载入时,系统会自动预定地址空间区域并把文件映像映射到该区域。

  9.当多个页交换文件位于不同的硬盘上时,系统可以同时写入多个硬盘,所以运行的更快。典型如Raid等。

  10.块是一些连续的页面,这些页面具有相同的保护属性,并且以相同类型的物理存储器作为后备存储器。

  11.注意给物理存储页指定页面保护属性相关的标识。注意:两个写时复制标识*_WRITECOPY,可以让几个进程共享相同的存储页,当其中某个进程需要写数据时,再为其在内存中调拨一份副本以保存需修改数据,这样该进程就可以用自己的副本来继续执行了。通过这种方式,能极大地提升系统的性能。   另外,通过使用Windows提供的数据执行保护(DEP)技术可以防止恶意代码写入到用于数据的内存区域,譬如线程栈等。

  12.只有访问已对齐的数据时,CPU的执行效率才最高。若CPU访问的数据未对齐,则可能引发异常,也可能会导致多次访问来取得错位数据。除IA-64的CPU以外,现在的x86和x64的CPU都支持CPU自动处理数据错位的错误。

原文地址:https://www.cnblogs.com/sier/p/5676437.html