测量过程内存使用量会产生极低(错误)的值

时间:2014-08-09 15:38:40

标签: c# performance .net-4.0

我有以下代码来启动和监控流程:

Process process = new Process();
process.StartInfo.FileName = "foo.exe";

long maxMemoryUsage = 0;

process.Start()

while(!process.HasExited)
{
    maxMemoryUsage = Math.Max(maxMemoryUsage, process.PrivateMemorySize64);
}

使用此代码运行大型应用程序后,根据任务管理器在其峰值时使用328 MB(内存“私有工作集”)。 maxMemoryUsage的值和process.PeakPagedMemorySize64的值是364544.根据MSDN,这个值应该被解释为字节,这意味着它有点超过300KB,距离预期值一千倍。另一个进程.Peak ...内存属性也报告极低的值(所有都在兆字节以下,除了PeakVirtualMemorySize64,这是4MB,我认为这是该字段的最小值)。

我尝试启动不同的应用程序(基于C#和C ++,我有源代码),我知道这些应用程序使用很少或很多内存,而且内存值总是非常接近这个过程中看到的值。显然我做错了。

所以我的问题是:如何衡量我从C#应用程序中生成的进程的最大内存使用量。 (注意,只要我知道程序退出后它的值,我就不需要ealtime值了,我也不需要超精确,因为我不在乎它是27.04MB还是30MB,但是我如果它是30MB或100MB,请小心。

编辑:这是一个完整的可重复测试用例

class Program
{
    static void Main(string[] args)
    {
        Process process = new Process();
        process.StartInfo.FileName = @"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe";

        long maxMemoryUsage = 0;

        process.Start();

        while(!process.HasExited)
        {
            maxMemoryUsage = Math.Max(maxMemoryUsage, process.PagedMemorySize64);
        }

        Console.Out.WriteLine("Memory used: " + (maxMemoryUsage / 1024.0) / 1024.0 + "MB");

        Console.ReadLine();
    }
}

根据任务管理器Visual Studio使用103MB。关闭Visual Studio后,程序报告0.3984375MB。

1 个答案:

答案 0 :(得分:5)

进程类被高度缓存。除非您调用Refresh方法,否则无论您阅读某些属性多少次,您都只能获得缓存结果。您需要致电Process.Refresh以获取非缓存结果。

引用msdn

  

当Process组件与流程资源相关联时,   根据过程立即填充Process的属性值   相关流程的状态。 如果有关的信息   相关过程随后发生变化,这些变化不是   反映在流程组件的缓存值中。过程   component是过程资源的快照   相关。要查看关联过程的当前值,   调用Refresh方法。

因此,您的代码将变为:

while(!process.HasExited)
{
    process.Refresh();
    maxMemoryUsage = Math.Max(maxMemoryUsage, process.PrivateMemorySize64);
}

另外,您可以考虑查看process.PeakXXX属性,这对我来说会有所帮助。