http://blog.sina.com.cn/s/blog_66d835040100uy3x.html
《Windows核心编程(第5版)》第13章Windows内存体系结构,本章将深入探讨Microsoft Windows所使用的内存体系结构。本节为大家介绍的是物理存储器和页交换文件。
AD:
13.5 物理存储器和页交换文件
在老式的操作系统中,物理存储器被认为是机器中内存的总量。换句话说,如果一台机器装有16 MB内存,那么应用程序最多可以使用16 MB内存。当今的操作系统能让磁盘空间看起来像内存一样。磁盘上的文件一般被称为页交换文件(paging file),其中包含虚拟内存,可供任何进程使用。
当然,为了能够使用虚拟内存,操作系统需要CPU的大力协助。当线程试图访问存储器中的一个字节时,CPU必须知道该字节是在内存中还是在磁盘上。
从应用程序的角度来说,页交换文件以一种透明的方式增大了应用程序可用内存(或存储器)的总量。如果一台机器装备了1 GB的内存,硬盘上还有1 GB的页交换文件,那么应用程序会认为可用内存的总量为2 GB。
当然,这台机器实际上并没有装备2 GB的内存。实际上,是操作系统与CPU分工协作,把内存中的一部分保存到页交换文件中,并在应用程序需要的时候再将页交换文件中的对应部分载入内存。因 此,使用页交换文件可以增大应用程序可用内存的总量。另一方面,页交换文件的使用并不是必须的。如果一台机器没有页交换文件,那么对系统来说,它只是认为 可供应用程序使用的内存总量减少了。但是,我们强烈建议用户使用页交换文件,这样就可以运行更多的应用程序,而应用程序也可以操作更多的数据。最好是把物 理存储器看成是保存在磁盘(通常是硬盘)上的页交换文件中的数据。当应用程序调用VirtualAlloc函数来把物理存储器调拨给地址空间区域时,该空 间实际上是从硬盘上的页交换文件分配得到的。系统中页交换文件的大小是决定应用程序可用内存总量的最重要因素,机器实际装备的内存总量对它的影响相对较 小。
当一个线程试图访问所属进程的地址空间中的一块数据(位于第17章介绍的内存映射文件之外)时,有可能会出现两种情况。图13-2显示了经简化后的 流程图。(更多细节请参阅Mark Russinovich和David Solomon所著的Microsoft Windows Internals,由微软出版社出版。)
第一种情况是,线程要访问的数据就在内存中。在这种情况下,CPU会先把数据的虚拟内存地址映射到内存的物理地址,接下来就可以访问内存中的数据了。
第二种情况是,线程要访问的数据不在内存中,而是位于页交换文件中的某处。在这种情况下,这次不成功的访问被称为页面错误。发生页面错误时,CPU 会通知操作系统。操作系统随即在内存中找到一个闲置的页面,如果找不到,操作系统必须先释放一个已分配的页面。如果待释放的页面没有修改过,那么操作系统 可以直接释放该页面。但如果系统需要释放一个修改过的页面,那么它必须先把页面从内存复制到页交换文件。接下来,系统会在页交换文件中对所需访问的数据块 进行定位,并把数据载入到内存中闲置的页面。然后,操作系统对它内部的表项进行更新,以反映该块数据的虚拟内存地址现在已经被映射到了内存中对应的物理内 存地址。这时CPU会再次运行那条引发页面错误的指令,但和前一次不同的是,这一次CPU能够将虚拟内存地址映射到物理内存地址并成功访问所需的数据。
图13-2 把虚拟地址转换为物理存储器地址 |
系统需要在内存和页交换文件之间复制页面的频率越高,硬盘颠簸(thrash)得越厉害,系统运行得也越慢。(颠簸是指操作系统把所有的时间都花在 在页面文件和内存之间交换数据上,导致没有时间运行程序。)通过给计算机添加更多的内存,我们可以减少应用程序运行时可能产生颠簸的次数,从而极大地提高 应用程序的性能。这里有一条经验法则:要让计算机跑得更快,最好是增加内存。实际上,和换个更快的CPU相比,添加内存在大多数情况下都会得到更好的性能 提升。
不在页交换文件中维护的物理存储器
在读过上一节之后,读者可能会想,如果有许多程序同时运行,页交换文件可能会变得相当大--尤其是每次运行一个程序时,系统都必须为该进程的代码和 数据预订地址空间区域,为这些区域调拨物理存储器,然后把硬盘上的程序文件中的代码和数据复制到页交换文件中已调拨的物理存储器中去。
事实上,系统并不会执行刚才所说的这些操作。如果系统确实这么做的话,那么载入一个程序并让它运行起来会花费很长的时间。当用户要求执行一个应用程 序时,系统会打开该应用程序对应的.exe文件并计算出应用程序的代码和数据的大小。然后系统会预订一块地址空间,并注明与该区域相关联的物理存储器就 是.exe文件本身。是的,系统并没有从页交换文件中分配空间,而是将.exe文件的实际内容(或文件映像,即file image)用作程序预订的地址空间区域。这样一来,不但载入程序非常快,而且页交换文件也可以保持一个合理的大小。
当把一个程序位于硬盘上的文件映像(即一个.exe或DLL文件)用作地址空间区域对应的物理存储器时,我们称这个文件映像为内存映射文件 (memory mapped file)。当载入一个.exe或DLL时,系统会自动预订地址空间区域并把文件映像映射到该区域。但是,系统也提供了一组函数,可以让开发人员把数据文 件映射到地址空间。我们会在第17章详细讨论内存映射文件。
Windows可以使用多个页交换文件。如果多个页交换文件位于不同的物理硬盘上,那么系统就可以运行得更快,这是因为系统能同时写入多个硬盘。在控制面板里,我们可以通过以下步骤来添加和删除页交换文件。
(1)选择Performance Information And Tools(性能信息和工具)。
(2)单击Advanced Tools(高级工具)链接。
(3)单击Adjust The Apperance And Performance Of Windows(调整Windows的外观和性能)链接。
(4)选择Advanced(高级)选项卡,并在虚拟内存部分单击Change(更改)按钮。
下图显示了弹出的对话框。
说明 当Windows从软盘载入.exe或DLL文件时,系统会把整个文件从软盘复制到内存中。此外,系统还会从页交换文件中分配足够的存储空间来存放文件映 像。只有当系统需要把一个页面换出内存,而页面又包含该文件映像的一部分时,系统才会写入页交换文件。如果系统的内存负载很轻,那么文件总是从内存中直接 运行。
Microsoft必须让在软盘上执行的文件以这种方式运行,因为只有这样安装程序才能正常运行。通常,安装程序从第一张软盘开始运行,在安装过程 中用户会取出该软盘并插入其他软盘。如果系统需要再从第一张软盘去加载.exe或DLL的一部分代码,那么很显然,第一张软盘可能已经不在软驱内了。但 是,由于系统已经把文件复制到了内存中(并以页交换文件为后备存储器),因此系统可以随时访问安装程序而且不会遇到任何问题。
除非映像文件是用/SWAPRUN:CD或/SWAPRUN:NET开关链接的,否则系统不会把位于其他可移动媒介(比如,光盘或网络驱动器)上的映像文件复制到内存中的。