Windows - 提交大小 vs 虚拟大小

39
我想了解任务管理器中的提交大小和SysInternals'的Process Explorer中的虚拟大小之间的确切区别。在Process Explorer中,虚拟大小参数似乎是进程总虚拟内存使用的更准确指示。但是,提交大小始终小于虚拟大小,我想它不包括进程正在使用的所有虚拟内存。我希望有人能解释这些参数到底包括了什么。
3个回答

68

内存可以被保留、提交、首次访问并成为工作集的一部分。当内存被 保留 时,一部分地址空间被留出,其他什么也不会发生。

当内存被 提交 时,操作系统保证对应的页面原则上可以存在于物理RAM中或者页面文件中。换句话说,它计入系统可用总页面数的硬限制,并且 正式地 创建页面。也就是说,它创建页面并假装它们存在(实际上它们还没有存在)。

当内存首次被访问时,正式存在的页面被创建,使得它们 真正 存在。进程要么获得一个零页面,要么从映射中读取数据到页面中。页面被移到进程的 工作集 中(但不一定永久驻留在那里)。

每个正在运行的进程都有一些页面 事实上和逻辑上 在RAM中,这些页面存在,而且它们也"官方"存在。这是进程的工作集。
此外,每个运行中的进程都有一些页面 事实上 在RAM中,但已经不再在RAM中"官方"存在。它们可能在所谓的 "备用列表 "上,或者是缓存的一部分,或者是其他内容。当这些页面被访问时,操作系统可能会将它们简单地再次移回到工作集中。
最后,每个进程都有一些页面完全不在RAM中(要么在交换空间中,要么尚未存在)。

虚拟大小 包含进程已经 保留 的所有页面的大小。

提交大小 仅包括已经 提交 的页面。

换句话说,“虚拟大小”基本上是你自己的问题,只受到地址空间大小的限制,而“提交大小”是每个人都面临的问题,因为它消耗了全局有限的资源(RAM加上交换空间)。它因此影响其他进程。

1
很难说。两者都可能是内存泄漏或其指标,但它们是不同的东西。当您的虚拟大小达到2GB(或由于碎片化而更早,或由于/3G而更晚),您最终将耗尽地址空间,因此进一步的分配将获得“内存不足”错误,尽管在原则上可能有足够的RAM可用。通常,“不断上升而永远不再下降”是不好的,但如果_commit_再次下降,这可能只是堆管理器保留内存(但正确未提交),这将是可以接受的。您是否遇到实际的内存不足条件? - Damon
1
碎片化的问题在于,即使有足够的内存,也可能会使分配器难以提供内存。例如,std::vector 用于增长的典型模式对于分配器来说是一场噩梦:分配一个更大的块,复制,然后释放较小的块。然后再分配另一个更大的块,复制,释放第二个块。由于块大小永远不符合您要求的大小(幸运的是,这是一个罕见事件,因为 vector 呈几何增长),因此无法以有用的方式回收已释放的内存,但您可能会使用类似的分配模式。 - Damon
1
所以,如果您在应该有足够内存的情况下遇到崩溃,那么很可能是因为出现了碎片化。尝试小心地选择分配/释放模式,尽早保留空间而不是动态增长,并且如果适用,分配更大的对象池(重复使用的对象池可以产生奇效)。还要注意,分配器具有应对的最小大小(通常为16字节,因为它对齐到8字节并需要存储簿记信息),因此分配许多非常小的对象对分配器来说也是“毒药”。 - Damon
2
不要将“提交大小”(由任务管理器报告)与“已提交页面”混淆。提交大小是未受内存映射文件(例如二进制代码页)支持的内存量。已提交页面是虚拟内存的一个段,包括所有可寻址的页面(而非空闲或保留)。 - josh poley
1
完全位置无关代码,正如您所指出的那样,是通常不计入提交的映射的一个例子(但其他部分可能会计入)。此外,您是正确的,任务管理器中显示的数字与页面数之间的差异相当于页面大小(但这只是一个演示细节)。尽管如此,这段内存肯定是以完整页面的形式提交的,而且它是相同的数字,只是在特定工具中显示的数字更大。除了完整页面之外,根本不可能提交任何东西(这也不是100%正确的,因为分配粒度为64k)。 - Damon
显示剩余5条评论

9
提交大小是为进程保留在分页文件中的空间量。 当其页面需要被交换出以为其他进程腾出RAM空间时使用。
是的,虚拟内存大小将更大,因为它包括未由分页文件支持的页面。 至少 EXE 和非重新定位的DLL 中的代码和资源部分属于此类。 必要时,这些页面可以简单地被丢弃并从文件中重新加载。 所有操作系统DLL都符合此类别。 此外,进程使用的任何内存映射文件也属于此类别。 SysInternals的VMMap实用程序可以提供洞察力。

2

虚拟大小是进程的虚拟地址空间大小。

在分配内存时,您可以请求一个地址范围,而不实际分配其后面的内存。这些地址不指向物理内存,直到使用第二个分配调用来提交它们为止。

了解更多信息,请访问VirtualAlloc。Linux 有执行相同操作的 mmap 函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接