突破Windows极限:物理内存

译者:在前些天的一个业务问题追踪系统句柄泄漏的时候发现了这个系列的文章,由于目前中文技术环境的情况,这一类涉及基础概念的精品文章凤毛麟角,而看到这个系列在2008年就已经开始更新,感觉非常的感慨与失落,就决定将这个系列在业余时间逐步查阅资料翻译并分享出来。


原文地址:Pushing the Limits of Windows: Physical Memory  @  Mark Russinovich

译者:该篇以及后续几篇以“突破Windows极限”系列的文章都为译文,原作者Mark Russinovich拥有其原文所有权限,如果在翻译过程中存在个人水平问题导致的错误,以原文为准。在译文中所有引用的图片所有权归原文作者所有。


这是在接下来的几个月中我要完成的名为“突破Windows极限”系列的博客的第一篇,这个系列将会描述 Windows 和应用程序如何使用具体的资源,在使用这些资源时的限制与许可,如何测量资源的用量以及怎样监测泄漏情况。为了更好更有效率地使用 Windows ,需要弄清楚 Windows 是怎样管理物理资源,例如CPU和(物理)内存,以及如果使用和管理逻辑资源,例如虚拟内存,句柄和 Windows 管理器对象。在弄清楚了这些资源的使用限制以及怎么追踪它们的用量之后我们才能够更精准地为程序分配使用这些资源,才能够更好地为关键工作分配合适的资源,并能够准确地追踪资源的泄漏。

下面是这个系列的目录,尽管它们相互独立,但还是尽量以列出的顺序阅读。

  • 突破Windows极限:物理内存
  • 突破Windows极限:虚拟内存
  • 突破Windows极限:分页池和非分页池
  • 突破Windows极限:进程和线程
  • 突破Windows极限:句柄
  • 突破Windows极限:用户对象和GDI对象(一)
  • 突破Windows极限:用户对象和GDI对象(二)

物理内存

计算机中最基本的一个资源就是物理内存。 Windows 内存管理器主要负责为活动进程,设备驱动和操作系统自身分配内存。由于大多数系统能够访问的数据量远远大于实际上的物理内存容量,所以物理内存本质上是系统能够使用的代码以及数据的一个“窗口”。因此物理内存的总量与系统性能息息相关,因为当系统或者进程需要的数据无法在内存中找到时,内存管理器只能够去磁盘中寻找它们。

除了影响性能之外,物理内存的总量本质上也严重限制了其他资源。例如,非分页池与系统缓存都是在物理内存的基础上实现的,显然也受限于物理内存。另外,物理内存也限制着系统虚拟内存的大小,其大小大致相当于物理内存和系统所能管理的分页文件的总量。物理内存更直接地限制了系统中的进程数量,我们将在进程与线程的篇章解释为何如此。

Windows服务器的内存限制

Windows 所能够支持的内存总量由硬件、许可证、操作系统数据结构以及驱动兼容性限制。Memory Limits for Windows Releases这个MSDN页面记录了不同 Windows 版本以及相同 Windows 版本下的不同SKU版本对内存的限制。

我们可以看到所有Windows版本的内存支持的差异。例如32位的 Windows Server 2008 Standard 最大只能够支持4GB的内存而同样是32位的 Windows Server 2008 Datacenter 却最大能够支持64GB的内存,还有64位的 Windows Server 2008 Standard 最大能够支持32GB的内存而同样是64位的 Windows Server 2008 Datacenter 却能够支持高达2TB的内存。虽然并不存在多少配置了2TB的内存的系统,但是 Windows Server 性能小组却知道两台,其中一台在他们的实验室中,这是那台服务器的任务管理器的截图:

image

32位版本的 Windows Server 2003 Datacenter 存在最大128GB的内存的限制,而事实上内存管理器为了管理这么大的系统的物理内存需要消耗特别多的虚拟地址空间。内存管理器通过一个叫做PFN数据库的数组来追踪定位每个内存分页,为了性能考量,它将整个PFN映射到了虚拟内存中。因为表示一个内存分页需要28byte(字节)的数据结构,所以在一个支持128GB的内存的系统上PFN数据库将占用980MB。由于硬件限制,32位系统的虚拟内存空间最大只有4GB,默认情况下用户进程(如记事本)和系统平分地址空间,因此980MB将近占用了系统的虚拟地址空间的一半大小,仅仅剩下1GB留给系统内核、设备驱动、系统缓存和其他的系统数据结构。

image

这也是为什么上面MSDN的内存限制表降低了开启了4GB调整(4GB tuning译:未找到该术语中文翻译)的限制(也叫4GT,启用Boot.ini 的 /3GB 或者 /USERVA 开关,并在 Bcdedit 中设置/Set IncreaseUserVa启动选项),因为 4GT 将32位系统虚拟内存空间的3GB分配给用户进程将仅剩的1GB留给系统。为了提高性能,Windows Server 2008 通过限制其32位系统的最大支持内存总量为64GB从而保留了更多内存地址空间给系统。

内存管理器可以仅仅只在需要时才将更多的PFN数据库内容映射到系统地址空间,但是这一样也会导致复杂度的增加并且存在由于频繁的映射与取消映射的操作降低系统性能的可能性。直到现在系统配备的内存足够大这种方式才被考虑使用,由于64位系统并不需要将整个PFN数据库映射到系统地址空间,所以这个功能只是64位系统的一个可选项。

对于64位的 Windows Server 2008 Datacenter 的最大内存为2TB的限制并不是由于实现的困难或者硬件的约束,仅仅是微软只把自己能够测试的条件推荐出来,而在 Windows Server 2008 发布的时候,当时配置了最大内存的系统也只有2TB,所以 Windows 就把它设置为该版本的最大限制了。

Windows客户端的内存限制

64位的Windows客户端的各种SKU版本将支持不同规格的内存作为一个版本差异,从仅仅只支持512MB的 Windows XP Starter 到支持128GB的 Vista Ultimate 和支持了192GB的 Windows 7 Ultimate 。所有的32位版本的 Windows 包括了 Windows Vista, Windows XP 和 Windows 2000 Professional,都支持最大4GB的内存。4GB是基础的x86内存管理器所能够支持的最大物理地址空间。最初,甚至没有必要考虑在客户端上支持大于4GB的内存,因为就算在服务器上内存也很少。

但是到了 Windows XP SP2 在开发的时候就已经能够预见到很多客户端机器配置的内存将会大于4GB,所以 Windows 开发组开始在 Windows XP 上广泛地测试内存大于4GB的情况。 Windows XP SP2 在硬件层面上支持了物理内存扩展(Physical Address Extensions  (PAE)),原本是用来实现非执行内存保护(no-execute memory(NX))的,因为这是数据执行保护(Data Execution Prevention (DEP))的基础,但是这个技术同样可以用来支持大于4GB的内存。

但是 Windows 开发工程师发现许多客户端计算机由于一些设备驱动程序(比如,显卡、声卡驱动)的导致系统崩溃、挂起或者无法启动,而服务器上不存在这样的情况,因为这些驱动程序在设计与实现的过程中并没有考虑过内存大于4GB的情况,所以它们会将内存截断,导致了内存被破坏。而通常服务器系统使用更加通用的驱动程序,它们更加简单稳定,因此一般不会存在这种情况。正是因为这些存在问题的设备驱动程序,导致 Windows 开发决定将客户端的SKU版本设置忽略大于4GB地址的限制,尽管理论上它们可以正确地访问这些空间。

32位客户端有效地址限制

尽管32位客户端版本系统的内存限制是最大4GB,但是由于芯片组与连接的设备的限制,实际的最大内存限制会低于4GB。因为实际上的物理地址映射不仅仅只包括RAM,设备内存也包含在内,并且在32位与64位系统中,为了兼容性的考量,操作系统都会把设备地址映射在4GB的地址范围以内。假设有这么一台计算机,配置了4GB的内存(RAM)以及一些设备,比如显卡、声卡、网络适配器等等,且它们被分配的地址总和为500MB,那么500MB加上4GB就超过了4GB的内存地址上限,如下所示:

image

结果就是,如果你为你的计算机配置了超过3GB的内存,并且安装的是32位的操作系统,结果就是你并不能将所有的安装的内存充分利用。在 Windows 2000, Windows XP 和 Windows Vista RTM 中,你可以直接在系统属性对话框或者任务管理器的性能页面看到 Windows 能够访问多少内存,在 Windows XP 和 Windows Vista (以及 SP1)中你也可以通过 Msinfo32 或者 Winver 这样的工具来查看。在 Window Vista SP1 中,这些位置显示的内容就变为安装了多少内存,而不是有多少内存是可用的了,在微软的这个页面有记录这个变化。

在我的安装了4GB内存的笔记本上,当我启动的是32位的Vista时,在 Msinfo32 中显示的全部可用内存为3.5GB:

image

我们可以使用由 Alex Ionescu (将为我和 David Solomon 共同合作的 Windows Internals 工具集的第五版出一份力)编写的 Meminfo 工具来查看物理内存布局。这就是我在系统上用 Meminfo -r 显示出的物理地址的范围:

image

注意地址在从 9F0000 到 100000 以及从 DFE6D000 到 FFFFFFFF 的空缺。但是,当我使用64位的Vista再次做这个操作时,能够看到包括超过了4GB限制的那500MB的部分,所有安装的4GB的内存都是可用的:

image

到底是什么占用了那4GB内存中的空洞呢?设备管理器可以告诉我们结果,运行"devmgmt.msc",并在视图菜单中选择连接的资源,同时将内存节点展开。毫无意外,在我的笔记本上占据了最大的地址空间的设备是显卡,占据了 E0000000-EFFFFFFF 这段256MB的空间:

image

其他的一些设备占据了剩余地址中的大部分,其他的被PCI总线保留,以供系统启动时的固件使用。

高性能的游戏主机配置的显卡会消耗很大一部分的地址空间。比如说我购买了一台配有4GB的内存与两张1GB的显卡,没有特意指定系统版本,原以为会为我预装64位的Vista,结果他们为我安装了32位的版本,这样的结果就是那安装的4GB的内存中能够供我使用的只有2.2GB了。你可以看到当我把系统换成64位后从 8FEF0000 到 FFFFFFFF 之间的巨大的内存空洞:

image

设备管理器能够看到这2GB的空洞中的512MB被两张显卡消耗了(每块占用了256MB),并且看起来固件动态分配了剩余的更多的空间,或者说所显示的地址空间的只是保守的估计:

image

就算计算机只安装了2GB的内存,在32位系统中也不能够被充分利用,因为芯片组会为设备强制分配一部分空间地址。我们前一段时间从一个大型OEM厂商购买的一部家庭计算机,显示在安装了2GB的内存中有1.97GB是可用的:

image

地址空间中从 7E700000 到 FFFFFFFF 这一段被保留给了PCI总线以及一些其他设备,理论上剩余了 7E700000 字节(1.976GB),其中有一些也被设备保留,这就是为什么 Windows 显示只有1.97GB的内存是可用的:

image

因为现在设备供应商必须将32位与64位的驱动程序都提交给微软Windows硬件质量实验室(WHQL)来获得驱动签名,所以主要的设备厂商也开始着手于处理物理地址大于4GB的问题。但是32位的Windows将继续忽略大于4GB的地址空间,因为还有一些不可预料的风险,但是OEM厂商开始使用64位操作系统应该不能成为问题。或者说他们至少应该开始这样做。

最重要的是,你可以使用64位的操作系统来充分利用已经安装的内存,在你购买高端游戏设备的时候,应该强烈要求OEM厂商为你预装64位的操作系统。

是否有足够使用的内存?

不管系统能够利用多少内存,问题是它们够用吗?这并没有一个准确快速的解答,可以在运行内存密集型的程序的同时长时间观察系统性能中的“可用内存”来判断内存是否够用。顾名思义,可用内存是指内存管理器可以在需要的时候马上分配给进程或者系统的内存。当然,内存管理器会尽可能尝试将更多的内存用于文件缓存( file cache (the standby list) )或者清零内存( zeroed memory (the zero page list) ),比如Vista的Superfetch功能就能够将接下来可能使用到的数据放到内存中,并进行优先级排序,以提高性能。

如果内存变得不够用了,这说明系统或者进程正在大量消耗内存,如果可用内存长时间接近0,最好还是通过添加内存的方式来提高性能。有挺多追踪内存用量的方法,在Vista上,可以简单直接地使用任务管理器的内存使用历史来追踪内存的使用情况,以查看它是否长时间接近100%。这是我的8GB的内存的台式机的任务管理器的截图(emm,可能我的内存太大了):

image

在所有版本的Windows上,你都可以使用性能监视器,通过在内存性能计数器组中添加Available Bytes计数器来绘制可用内存:

image

你可以通过 Process Explorer 的系统信息对话框查看当前的内存使用情况,在 Windows Vista 之前的版本也可以在任务管理器的性能页面上看到这个值。

突破Windows极限

在CPU、内存与硬盘中,内存的多少极大地影响整机性能,当然,多多益善。64位系统是充分利用内存的前提条件,当然它的优势并不仅仅是能够最大限度地利用内存,在后面的篇章中我还会讲述虚拟内存的限制。


译者:原文地址中还有大量作者与读者的讨论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值