监控应用程序内存使用情况的正确方法是什么?

出于调试目的,我编写了这个小静态方法:

public static long CheckMemory(long maxMemorySizeBytes) { GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); var usedMemoryBytes = Process.GetCurrentProcess().VirtualMemorySize64; if (usedMemoryBytes > maxMemorySizeBytes) Debugger.Break(); return usedMemoryBytes; } 

出于某种原因, VirtualMemorySize64不断返回比Visual Studio Diagnostic Tools窗口显示的内存更多的内存,以及任务管理器显示的内容。 对于我现在正在运行的具体示例,以下是数字:

  • 诊断工具:~250 MB
  • 任务管理器:~120 MB
  • VirtualMemorySize64:~1100 MB

为什么会出现如此大的差异,如何从应用程序本身内正确跟踪内存使用情况?

VirtualMemorySize测量进程使用的所有虚拟内存。 其中包括计算机上所有其他进程共享的页面。 在.NET程序中包含操作系统,CLR,抖动和ngen-ed框架程序集。

诊断工具 – 显示应用程序的“ 私有字节”度量标准的实时图表。 Private Bytes是进程分配的内存总量的度量,不包括与其他进程共享的内存。

任务管理器中 ,默认情况下,您会看到“私有工作集”内存,该内存是进程使用的内存量,无法在其他进程之间共享。

所以:

如果您想了解您正在使用多少内存,请检索进程的VirtualMemorySizeWorking SetPrivate Bytes

  • 私有字节与任务管理器误导性地称为“VM大小”相同。
  • 工作集是任务管理器所谓的“内存使用”,它是进程的地址空间(“专用字节”加上内存映射文件)的一部分,当前驻留在RAM中并且可以在没有页面错误的情况下被引用。
  • VirtualMemorySize是进程的总虚拟地址空间,包括专用字节和内存映射的东西。

如果你将所有进程的VirtualMemorySize相加,你可能会发现它增加了比你实际拥有的内存更多的内存。 那是因为那些内存映射文件,EXE,DLL等可以在进程间共享; RAM中的相同物理页面可以同时在多个进程的地址空间中访问。