此系统信息来自Process Explorer。仍然有可用的物理内存,但是系统显示几乎没有RAM。
任务管理器还显示大约使用了总RAM的74%。
自安装Windows 8.1以来,计算机具有4 + 8 = 12 GB的RAM。我通过将4 GB更改为8 GB模块来对其进行了升级。这可能是问题吗?还是这种行为是正常现象,而我只是误解了可用物理内存的含义?
Ctrl+G
快捷方式上传图像,以便Stack Exchange可以防止图像随着时间的流逝而腐烂。
此系统信息来自Process Explorer。仍然有可用的物理内存,但是系统显示几乎没有RAM。
任务管理器还显示大约使用了总RAM的74%。
自安装Windows 8.1以来,计算机具有4 + 8 = 12 GB的RAM。我通过将4 GB更改为8 GB模块来对其进行了升级。这可能是问题吗?还是这种行为是正常现象,而我只是误解了可用物理内存的含义?
Ctrl+G
快捷方式上传图像,以便Stack Exchange可以防止图像随着时间的流逝而腐烂。
Answers:
弹出“内存不足”提示您用完了专用内存(一种虚拟内存)的限制。并不是说您用完了RAM(物理内存)。拥有多少可用内存都没有关系。拥有大量可用RAM不允许您超过提交限制。提交限制是您的总 RAM(无论是否正在使用!)加上当前页面文件大小的总和 。
相反,“用完”提交限制(主要是创建进程专用的虚拟地址空间)不一定使用任何RAM!但是,除非知道是否有存储空间,否则操作系统将不允许创建它。因此,您可以在不使用所有RAM甚至大部分RAM的情况下遇到提交限制。
这就是为什么您不应该没有页面文件就运行的原因。请注意,页面文件可能实际上从未写入过!但是,它仍然可以避免出现“内存不足”和“内存不足”错误。
Windows实际上没有错误消息指出RAM不足。您用完的是“提交限制”。
该版本的Process Explorer中的“系统”图命名不正确。它应标记为“承担费用”。(在我使用的版本中,它称为“系统提交”。更好,但仍不完全一致。)在任何情况下,图形的“当前”高度在文本部分的下方都显示为“ Commit Charge”-“当前”,图表的最大高度表示“提交费用”-“限制”。
“提交费用”是指由页面文件支持的虚拟地址空间(如果有的话)-换句话说,如果不能全部容纳在RAM中,则其余部分进入页面文件。(还有其他类型的vas,它们由其他文件支持-称为“映射的vas”-或必须一直保留在RAM中;后者称为“不可分页”。)“提交限制”是指可以“承担费用”。它等于您的RAM大小加上页面文件大小。
您显然没有页面文件(我可以告诉您,因为提交限制等于您的RAM大小),因此提交限制就是RAM大小。
显然,各种程序+操作系统几乎已使用了所有可能的最大提交。
这与多少可用或可用的RAM没有直接关系。是的,您有大约4.5 GB的可用RAM。这并不意味着您可以超过提交限制。承诺的内存不一定使用RAM,并且不受可用RAM数量的限制。
您需要重新启用页面文件-使用这个投入很大的内存,我建议使用16 GB的页面文件,因为您不想强迫操作系统将这么多的东西保留在RAM中,并且页面文件在工作时效果最佳有很多可用空间-否则增加更多RAM。多很多。为了获得良好的性能,您需要在RAM中留出足够的空间来存储代码和其他不受页面文件支持(但可以分页到其他文件)的内容。
(但仍然比Windows Internals的内存管理章节短很多。)
假设程序分配了100 MB的进程专用虚拟内存。这是通过带有“ commit”选项的VirtualAlloc调用完成的。这将导致“提交费用”增加100 MB。但是这种“分配”实际上并没有使用任何RAM!仅在首次访问某些新提交的虚拟地址空间时才使用RAM 。
(如果有的话)
首次访问新提交的空间几乎总是一次内存写操作(在写入之前读取新分配的私有vas几乎总是一个编程错误,因为严格来说它的初始内容是不确定的)。但是,当您第一次触摸新分配的vas页面时,读取或写入结果是页面错误。尽管“故障”一词听起来很糟糕,但是页面错误是虚拟内存OS中完全可以预料甚至是必需的事件。
为响应这种特定类型的页面错误,该寻呼机(操作系统的内存管理器的一部分,有时会缩写为“ Mm”)将:
之后,执行内存引用的代码将重新执行引发页面错误的指令,并且这次引用将成功。
我们说该页面已“错误地”进入了进程工作集和RAM中。在任务管理器中,该过程将在该过程的“私有工作集”中以一页(4 KB)的增量显示。并将可用物理内存减少一页。(在繁忙的机器上可能很难注意到后者。)
注意1:此页面错误不涉及从磁盘读取的任何内容。从未访问过的已提交虚拟内存页面不会在磁盘上开始存在;它在磁盘上没有地方读它从。它只是在先前可用的RAM页面中“实现”。从统计上讲,实际上,大多数页面错误都在RAM中解决,可以解决已在RAM中用于其他进程的共享页面,也可以解决页面缓存-备用列表或修改后的列表,或像这样的“零需求”页面。
注意2:这仅占用“可用”中的一页,即4096字节。通常,一次只能访问一页,因此永远不会碰到之前提交的地址空间,因为这是第一次“触摸”页面。一次做更多的事情不会有改善,也没有优势。这将花费n倍的时间。相比之下,当必须从磁盘读取页面时,会尝试某种程度的“预读”,因为磁盘读取中的大部分时间都在每次操作的开销上,而不是实际的数据传输。“已提交”数量为100 MB;一页或一页出现故障的事实并不会减少提交费用。
注3:假设我们有4 GB的“可用” RAM。这意味着我们可以在内存不足之前引用已经分配但从未引用过的提交内存大约一百万次(4 GB / 4096)。此时,如果我们有一个像David Cutler和Lou Perazzoli所预期的页面文件,则RAM中一些最长的引用页面将被保存在磁盘上,然后可用于解决这些较新的页面错误。(实际上,操作系统会在此之前启动诸如“工作集修整”之类的RAM回收方法,并且为了提高效率,将对页面文件的实际写入操作缓存并批处理在修改后的页面列表中,并且……)这些都不会影响“已提交”计数。但是,它与“提交限制”有关。如果没有空间容纳所有“
但是,让我们假设我们没有做更多的引用,而仍然有大约4GB的页面可用。现在,让我们假设相同的过程-或无关紧要-进行另一个VirtualAlloc,这次已提交200 MB。同样,这200 MB被添加到提交费用中,并且不会从可用空间中删除任何RAM。只是VirtualAlloc'ating地址空间不会占用相应数量的RAM,而具有低“可用” RAM不会限制VirtualAlloc可以使用的地址空间量(拥有高可用RAM也不会增加它)。
(好吧,好一点的开销,相当于每2 MB(如果您使用的是x86,非PAE系统,则为4 MB)用于一个页表的一页(可分页!)。虚拟地址空间分配,并且每个虚拟连续分配范围都有几十个字节的“虚拟地址描述符”。)
这样,就有可能-而且很普遍!-在仅使用少量RAM的同时要消耗大量的“承诺费用”。
因为“承诺费用”确实表示将来可能会使用存储空间。“提交限制”表示可用于保存此类分配的总存储量(RAM +页面文件空间),如果它们曾经被实际引用过,因此需要在某个地方存储。
当Mm批准VirtualAlloc请求时,它承诺-“做出承诺”-对分配区域的所有后续内存访问都将成功;它们可能会导致页面错误,但是所有这些错误都将得以解决,因为有足够的存储空间来保存所有这些页面的内容,无论是在RAM还是在页面文件中。Mm知道这一点是因为它知道有多少存储空间(提交限制)以及已经“承诺”了多少存储空间(当前的提交费用)。
(但是尚未完全访问所有这些页面,因此在任何给定时间都不一定要有实际的存储空间和承诺的存储量。)
如果您尝试使用VirtualAlloc,并且当前的提交费用加上请求的分配大小将使您超出提交限制,并且OS无法扩展页面文件以增加提交限制...,则会弹出“内存不足”弹出窗口,启动,然后该进程看到VirtualAlloc调用失败。大多数程序会在那时候举手致死。假设呼叫成功,某些用户会盲目按下,然后在尝试引用以为已分配的区域时失败。
再次(对不起,重复):拥有多少可用RAM无关紧要。操作系统已承诺RAM或页面文件空间将在需要时可用,但该承诺不会从“可用”中减去。可用RAM仅在首次引用已提交的vm时才会用尽,这是导致其“故障转移” ...即在物理内存中实现的原因。仅仅提交(=分配)虚拟内存并不能做到这一点。它仅占用可用的虚拟地址空间,并从中使用可用的虚拟地址空间。
但在“出内存不足”的情况下有许多人对提交的内存分配请求,操作系统中加入了当前承诺费这一neew请求的大小...,发现一共是更比提交限制。因此,如果操作系统批准了这个新的空间,并且在此之后引用了所有空间,那么将没有任何实际位置(RAM +页面文件)来存储所有空间。
操作系统将不允许这样做。即使在所有情况都“故障”的情况下,也不允许分配更多的vas,而在最坏的情况下,它无法保留空间。这就是“提交限制”的目的。
我告诉你三遍我告诉你三遍我告诉你三遍: “可用” RAM的数量无关紧要。所承诺的虚拟空间实际上尚未真正使用所有存储空间都没有关系。Windows无法“提交”到虚拟分配,除非将来“所有”都可以出错。
请注意,还有另一种类型的vas,称为“ mapped”,主要用于代码和访问大型数据文件,但不收取“ commit charge”费用,也不受“ commit limit”限制。这是因为它带有自己的存储区,即“映射”到该存储区的文件。“映射” vas的唯一限制是映射文件所具有的磁盘空间量,以及将它们映射到其中的进程中的可用vas量。
基本上,这是一个度量和记录保存问题。您已经在尝试VirtualAlloc调用并失败后查看系统。
假设您只剩下500 MB的提交限制,并且某些程序尝试将VirtualAlloc设置为600 MB。尝试失败。然后,您查看系统并说:“什么?还剩500 MB!” 实际上,到那时可能还剩下很多,因为到那时为止所讨论的进程可能已经完全消失了,因此所有先前分配的提交内存都已释放。
麻烦的是,你不能回头的时间,看看犯了什么费用是在页头尝试的时刻。而且您也不知道尝试的空间是多少。因此,您无法确切地看到尝试失败的原因,或者要使尝试生效还需要多少“提交限制”。
如果在上述情况下,OS可以扩展页面文件(即,将其保留为默认的“系统托管”设置,或者您可以对其进行管理,但是将最大值设置为大于初始值,并且有足够的可用磁盘空间),并且这样的扩展充分增加了提交限制,以使VirtualAlloc调用成功,然后... Mm扩展了页面文件,VirtualAlloc调用成功。
那就是当您看到“系统内存不足”时。这是一个早期警告,如果情况在不缓解的情况下继续进行,您可能很快会看到“内存不足”警告。是时候关闭一些应用了。我将从您的浏览器窗口开始。
不,不是。看,操作系统并没有真正“扩展”现有文件。它只是分配一个新的范围。效果与其他任何非连续文件非常相似。旧的页面文件内容保持原样。他们不必复制到新的地方或类似的地方。由于与页面文件大小相比,大多数页面文件IO都处于相对较小的块中,因此任何给定传输都将跨越范围边界的机会确实很少,因此,碎片化不会造成太大的伤害,除非它确实过多。
最后,一旦扩展中所有已“占用”空间的进程退出(如果不尽快,则在操作系统关闭时),将自动释放扩展区,并且页面文件将恢复为其先前的大小和分配-如果该文件先前是连续的,则它将再次如此。
因此,允许页面文件扩展充当了完全免费的安全网:如果您允许它,但是系统不再需要它,则系统将不会像通常所说的那样“不断地扩展和收缩页面文件”,因此不会花费任何费用。而且,如果您确实需要它,它将使您免于因“虚拟内存不足”错误而崩溃的应用程序。
我已经在数十个网站上阅读过,如果您允许页面文件扩展,Windows将不断扩展和收缩该页面文件,这将导致该页面文件碎片化,直到您对其进行碎片整理为止。
他们只是错了。
如果您从未看到“内存不足”(或在较旧版本中为“虚拟内存不足”)弹出窗口,则操作系统从未扩展过您的页面文件。
如果您确实看到该弹出窗口,则表明您的初始页面文件大小太小。(我希望将其设置为最大观察到的使用量的4倍;即,“%pagefile使用量峰值” perfmon计数器应低于25%。原因:Pagefile空间的管理方式与其他任何堆一样,并且在拥有大量可用空间的情况下效果最佳玩。)
有人可能会辩称,如果没有可用的RAM来解决页面错误,则OS应该只是让分配发生,然后让引用失败。换句话说,在上面我们描述了初始页面错误的工作方式的上方,如果由于没有可用空间并且没有位置而无法完成“分配RAM的可用物理页面”(步骤1)该怎么办?留下任何内容以使其可用吗?
这样,寻呼机将无法解决页面错误。它必须允许将异常(页面错误)报告回有故障的线程,可能已更改为其他一些异常代码。
设计理念是,如果您用尽了提交限制,VirtualAlloc将返回零(从技术上讲是NULL指针)而不是地址,并且完全可以期望程序员知道VirtualAlloc调用会失败。因此,程序员应该检查这种情况并做出合理的响应(例如给您机会保存您的工作,然后“优雅地”结束程序)。(程序员:您确实检查了从malloc,new等返回的NULL指针,是吗?那为什么不从中返回?)
但是程序员不必期望像这样的简单内存引用
i = 0; // initialize loop counter
可能会失败-如果位于成功提交的地址空间区域中则不会。(或者,映射的地址空间。)但是,如果遵循“允许过量分配,让内存引用失败”的哲学,那将会发生。
不幸的是,像上面的代码行中那样的内存引用只是没有一种方便的方式来返回不良状态!它们应该工作,就像加法和减法一样。报告此类故障的唯一方法是作为例外。因此,要处理它们,程序员将不得不将整个程序包装在异常处理程序中。(尝试...抓住等等。)
可以做到...但是对于处理程序而言,处理程序很难知道如何“做正确的事”,因为在代码中可能会出现很多很多点。(具体来说,它们可能出现在每个引用VirtualAlloc的内存,使用malloc或new分配的内存以及所有局部变量的内存引用上,因为堆栈也是VirtualAlloc的。)
简而言之,要使程序在这种情况下无法正常运行会非常困难。
另一方面,检查从VirtualAlloc返回的NULL指针(或malloc或new,虽然不是完全一样),然后再做一些合理的事情,就像不尝试去做一样,这很容易继续执行该程序所需的虚拟空间。并可能询问用户是否要保存到目前为止的工作(如果有)。(当然,太多的应用程序甚至都不会花那么多时间。)
顺便说一下,操作系统的各种分配(例如分页和非分页池,PFN列表等)不会减少“提交限制”。这些只是在发生时收取费用。视频RAM甚至视频RAM“窗口”大小也不影响提交费用或提交限制。
您可以使用SysInternals网站上的testlimit工具演示所有这些内容。选项-m将分配已提交的地址空间,但不会“触摸”它,因此不会导致分配RAM。而选项-d将分配和引用页面,从而导致提交费用增加和可用RAM减少。
Russinovich,Solomon和Ionescu的Windows Internals。甚至还有一些演示,使您可以使用testlimit工具来证明所有这些点。但是,我必须警告您,如果您认为这太长了,请注意:仅Mm章节为200页;上面是一个极简版本。(也请浏览简介中的“致谢”部分。)