为什么在Windows Vista上调用GlobalMemoryStatus中的可用物理内存(dwAvailPhys)>可用虚拟内存(dwAvailVirtual)x64

问题描述:

我正在玩MSDN示例进行内存压力测试(请参阅:http://msdn.microsoft.com/en-us/magazine/cc163613.aspx)以及该工具的扩展吃物理记忆(见http://www.donationcoder.com/Forums/bb/index.php?topic=14895.0;prev_next=next)。虽然虚拟和物理内存之间的差异让我感到困惑。我认为每个进程都有2GB的虚拟内存(尽管我也因为“开销”而读取了1.5GB。我的理解是这个虚拟内存中的一些/全部/没有可能是物理内存,以及物理内存的数量进程可能会随着时间而改变(内存可能会换成光盘等)我进一步认为,一般来说,当您分配内存时,操作系统可能会使用物理内存或虚拟内存,因此我总结dwAvailVirtual应该始终如果我的问题没有很好地形成,我很抱歉,我仍然在努力,但是,我经常(总是)看到相反的结果。让我的头脑在Windows中的整个内存管理系统中得到解决。教程/说明/书籍recs是最受欢迎的!为什么在Windows Vista上调用GlobalMemoryStatus中的可用物理内存(dwAvailPhys)>可用虚拟内存(dwAvailVirtual)x64

安德鲁

虚拟内存量受地址空间大小的限制 - 每个进程在32位系统上的大小为4GB。您必须从中减去为系统使用保留的区域大小以及进程已经使用的虚拟机数量(包括映射到其地址空间的所有库)的大小。另一方面,物理内存总量可能高于系统为您的进程腾出的虚拟内存空间量(现在通常是这些天)。

这意味着如果您的存储空间超过〜2GB或RAM,则无法在一个进程中使用所有物理内存(因为没有足够的虚拟内存空间来映射它),但它可以被多个流程。请注意,该限制在64位系统中被删除。

+0

啊!我想我错过了一些基本的东西,而你(懒鬼)似乎正在指出它。 dwAvailVirtual是否指向该进程的可用内存,而dwAvailPhys是指整个系统的可用RAM?那么通常dwAvailPhys> dwAvailVirtual会有意义。这个过程几乎可以用完所有的2GB(或4GB?),但是仍然有大量的物理内存可用(用于其他进程)。 谢谢,Andrew – Dave 2010-03-17 23:19:05

+0

另外,你说每个进程在32位系统上获得4GB 。然后你提到2GB?每个进程的限制是什么?什么是外行的解释?32位如何转换为4GB? 谢谢 – Dave 2010-03-17 23:21:01

+0

就是这样。每个进程都有自己的虚拟内存空间,而物理内存(显然)是由整个系统共享的,一个32位的数字可以有2^32 = 4G的不同值,如果它被用作字节地址,这意味着它可以寻址4G不同的字节,现在它的一部分保留给内核使用,并且内核地址不能用于用户代码,在Win32上,默认情况下是2GB的地址空间 - 在第二个地址空间剩下2GB e应用程序。 – slacker 2010-03-18 18:17:54

这只是在过去的日子,当内存昂贵的时候。操作系统根据需要将虚拟内存页面映射到RAM。如果没有足够的RAM来满足程序的请求,它将开始取消映射页面以腾出空间。如果这样的页面包含数据而不是代码,它将被写入分页文件。只要程序再次访问该页面,它就会产生一个分页错误,让操作系统从磁盘读回页面。

如果机器内存很少,消耗虚拟内存页面的进程很多,那么可能会引起非常不愉快的效果,称为“抖动”。操作系统不断访问磁盘,机器性能变慢。

更多的RAM意味着更少的磁盘访问。没有理由不在32位操作系统上使用3 GB或4 GB的RAM,它很便宜。即使你没有使用全部4 GB,但由于在地址总线上占用空间的硬件设备(主要是视频),并非全部都是可寻址的。但是这不会改变用户代码可访问的虚拟内存的大小,它仍然是2千兆字节。

Windows Internals是一本很好的书。

+0

谢谢。将购买Windows内部。 – Dave 2010-03-17 20:51:51

+0

在32位机器上,2 GB VA限制是每个进程。我提出这个问题是因为一个普遍的误解是它跨越了所有的过程。因此,只要涉及多个进程,用户代码就可以利用超过2 GB的优势。还有一个/ 3GB的Windows操作系统启动开关,使这个限制为3GB,而不是... – 2010-03-18 03:55:24

我不知道这是不是你的问题,但MSDN page for the GlobalMemoryStatus function包含以下警告:

在有超过4 GB的内存的计算机上,GlobalMemoryStatus函数可以返回不正确的信息,报告值为-1表示溢出。因此,应用程序应该使用功能代替。

此外,该网页说:

在具有超过2 GB和小于4 GB的内存英特尔的x86计算机上,GlobalMemoryStatus功能将始终在dwTotalPhys返回2 GB成员MEMORYSTATUS结构。同样,如果总可用内存在2到4 GB之间,那么MEMORYSTATUS结构的成员将向下取整为2 GB。如果使用链接器选项将可执行文件链接起来,那么函数将返回两个成员中正确数量的物理内存。

既然你指的是像dwAvailPhys代替ullAvailPhys成员,这听起来像您使用的是MEMORYSTATUSEX结构的MEMORYSTATUS结构,而不是。我不知道在64位平台上会有什么后果,但是在32位平台上肯定会导致报告不正确的内存大小。

+0

谢谢丹尼尔。我在MSDN上看到了这一点,并且已经注意到了这一点。但是,我不认为这会影响我。警告说,dwAvailPhys membor可能在它的真正价值之下。它被截断为2GB。这很好(现在)。我不明白的是为什么物理内存不止是虚拟内存。再次,这可能源于我完全的无知。它确定似乎总是dwAvailVirtual> = dwAvailPhys,但显然并非如此。我有4 GB的内存(1stwarning大于4 GB)。我想我会试试Ex,以防万一我得到虚假价值。 – Dave 2010-03-17 20:45:58