我想了解任务管理器中的提交大小和SysInternals'的Process Explorer中的虚拟大小之间的确切区别。在Process Explorer中,虚拟大小参数似乎是进程总虚拟内存使用的更准确指示。但是,提交大小始终小于虚拟大小,我想它不包括进程正在使用的所有虚拟内存。我希望有人能解释这些参数到底包括了什么。
内存可以被保留、提交、首次访问并成为工作集的一部分。当内存被 保留 时,一部分地址空间被留出,其他什么也不会发生。
当内存被 提交 时,操作系统保证对应的页面原则上可以存在于物理RAM中或者页面文件中。换句话说,它计入系统可用总页面数的硬限制,并且 正式地 创建页面。也就是说,它创建页面并假装它们存在(实际上它们还没有存在)。
当内存首次被访问时,正式存在的页面被创建,使得它们 真正 存在。进程要么获得一个零页面,要么从映射中读取数据到页面中。页面被移到进程的 工作集 中(但不一定永久驻留在那里)。
每个正在运行的进程都有一些页面 事实上和逻辑上 在RAM中,这些页面存在,而且它们也"官方"存在。这是进程的工作集。
此外,每个运行中的进程都有一些页面 事实上 在RAM中,但已经不再在RAM中"官方"存在。它们可能在所谓的 "备用列表 "上,或者是缓存的一部分,或者是其他内容。当这些页面被访问时,操作系统可能会将它们简单地再次移回到工作集中。
最后,每个进程都有一些页面完全不在RAM中(要么在交换空间中,要么尚未存在)。
虚拟大小 包含进程已经 保留 的所有页面的大小。
提交大小 仅包括已经 提交 的页面。
换句话说,“虚拟大小”基本上是你自己的问题,只受到地址空间大小的限制,而“提交大小”是每个人都面临的问题,因为它消耗了全局有限的资源(RAM加上交换空间)。它因此影响其他进程。虚拟大小是进程的虚拟地址空间大小。
在分配内存时,您可以请求一个地址范围,而不实际分配其后面的内存。这些地址不指向物理内存,直到使用第二个分配调用来提交它们为止。
了解更多信息,请访问VirtualAlloc。Linux 有执行相同操作的 mmap 函数。
std::vector
用于增长的典型模式对于分配器来说是一场噩梦:分配一个更大的块,复制,然后释放较小的块。然后再分配另一个更大的块,复制,释放第二个块。由于块大小永远不符合您要求的大小(幸运的是,这是一个罕见事件,因为vector
呈几何增长),因此无法以有用的方式回收已释放的内存,但您可能会使用类似的分配模式。 - Damon提交大小
是未受内存映射文件(例如二进制代码页)支持的内存量。已提交页面
是虚拟内存的一个段,包括所有可寻址的页面(而非空闲或保留)。 - josh poley