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

时间:2017-09-11 10:05:07

标签: c# .net memory memory-leaks

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

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

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

1 个答案:

答案 0 :(得分:9)

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

诊断工具 - 显示应用程序的专用字节数指标的实时图表。 Private Bytes是进程分配的内存总量的度量,不包括与其他进程共享的内存。

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

<强>所以:

如果您想了解自己使用了多少内存,请检索 VirtualMemorySize 工作集和 私有字节

  • 私有字节 与任务管理器误导性地称为&#34; VM Size&#34;。
  • 相同。
  • 工作集 是任务管理器调用的内容&#34;内存使用情况&#34;,这是流程的一部分&#39;地址空间(&#34;专用字节&#34;加上内存映射文件),当前驻留在RAM中,可以在没有页面错误的情况下被引用)。
  • VirtualMemorySize 是进程的总虚拟地址空间,包括专用字节和内存映射内容。

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