在使用Windows的多年中,我习惯了任务管理器。 从那里,我以不良行为杀死了数百个应用程序。 在那儿,他看着其中的人消耗资源。 在我开始使用具有数百GB内存的机器之前,应用程序都有相应的请求。 本文讨论了为什么任务管理器不能很好地跟踪内存以及作为回报使用什么。 首先,关于Windows中的内存分配机制。
tl; dr:任务管理器隐藏有关分页内存和进程虚拟空间的信息。 最好使用Sysinternals捆绑包中的Process Explorer。
Windows分配
启动新进程时,操作系统会为此进程分配一个连续的地址空间。 在32位系统上,此空间可以为4 GB,对于内核,通常为2 GB,其余空间用于进程。 本文将忽略核心内存的使用。 在64位系统上,进程保留的内存可以增长到高达64 TB。 当我们实际拥有8 GB的内存时,此过程将用几TB的内存做什么? 首先,您需要了解什么是保留和传输的内存。
保留和传输的内存
并非这个巨大的地址空间的所有部分都是平等的。 实际上,物理RAM或磁盘都支持进程地址空间的某些部分(请参见下文)。 如果操作系统在尝试使用它时向您提供了该内存,则保留内存被视为已提交。 地址空间的其余部分(这是绝大多数)仍然可供保留。 就是说,并非总是OS可以为您提供此内存块供使用:例如,它可以在磁盘(交换文件)上进行复制,也可以不进行复制。 在C ++中,通过调用
VirtualAlloc保留内存。 因此,传输的内存是OS中硬件受限的资源。 让我们看看。
操作系统交换文件
交换文件是一个好主意。 基本上,操作系统
了解到您的应用程序并未特别使用内存的某些部分。 为什么要在上面花费实际的物理内存? 相反,内核进程会将未使用的片段写入磁盘。 在他们再次转向他之前,他只会回到记忆中。
有关Windows中内存如何工作的更详细说明,我推荐Mark Russinovich的讲座
“内存管理的秘密” 。
记忆追踪
有很多值得观察和分析的地方。 与谁联系? 当然,要任务管理器!
RAM内存通常称为工作集,而所有分配的内存通常称为专用字节。 DLL混淆了定义,因此暂时将其忽略。 换句话说:
Private Bytes [ ] = +
默认情况下,任务管理器准确显示任何进程的工作集:

这就是我一直在看的号码。 我怎么知道在任务管理器中有关已传输内存的信息在“
Commit Size
列中。 我在那里找不到有关虚拟内存的信息。
如果右键单击各列并选择相应的项目,则任务管理器允许您添加有关已传输内存的信息。有效内存指标
幸运的是,还有许多其他资源可用于跟踪资源。 PerfMon(系统监视器)安装在每台Windows机器上,它提供有关每个进程和整个系统的非常详细的信息:

有趣的是,系统监视器实际上可以检查和比较网络上两台或更多台计算机上的指标。 这是一个非常强大的工具,但是任务管理器显然更加用户友好。 我建议将
Process Explorer作为中间解决方案:

oom! Visual Studio,为什么仍处于32位模式(请注意其虚拟大小)? 我的计算机上的峰值内存使用量仍然是最大内存使用量的89%。 稍后将派上用场。
另外:许多人指出了其他方便的工具,包括
VMMap和
RAMMap 。
调试内存信息
幸运的是,这些并不是不必要的操作系统琐事。 有关内存消耗的实际信息已经多次帮助我调试各种问题。
最重要的是找到分配的内存中
未触及的部分。 交换数据也很重要:此内存已传输,但很少使用或根本没有使用。
即使有时使用内存,也必须了解这是一种昂贵的资源,因此您绝对不要走这条路。 内存泄漏将出现在这里。
由于这些原因,我之前曾听到过建议完全删除页面文件,并将分配的内存等同于工作集。 但是,这是一个双重想法。 然后,如果应用程序操作不正确,有时会徒劳地保留内存,则操作系统将无法转储内存。