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

9

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

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窗口和任务管理器显示的内存数量要多得多。就我现在运行的特定示例而言,以下是数字:

  • Diagnostic Tools:约250 MB
  • 任务管理器:约120 MB
  • VirtualMemorySize64:约1100 MB

为什么会有如此大的差异,如何正确跟踪应用程序内部的内存使用情况?

1个回答

12

VirtualMemorySize 衡量了进程使用的所有虚拟内存,包括与您机器上所有其他进程共享的页面。 在 .NET 程序中,这包括操作系统、CLR、jitter 以及 ngen-ed 框架组件。

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

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

因此:

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

  • Private Byte 是任务管理器误导性地称为“VM Size”的东西。
  • Working Set 是任务管理器称为“Mem Usage”的内容,它是进程地址空间(“Private Bytes”加上内存映射文件)中当前驻留在 RAM 中并且可以被引用的部分。
  • VirtualMemorySize 是进程的总虚拟地址空间,包括私有字节和内存映射内容。

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


8
非常好的回答,非常感谢。对于特别关注C#的人们,仅供参考:私有字节Process.PrivateMemorySize64,而工作集Process.WorkingSet64 - relatively_random

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