C# Winforms 应用程序中总进程内存使用情况的矛盾报告

Contradictory reporting of total Process memory usage in C# Winforms app

编辑:赏金已过期,但如果社区愿意将其奖励给某人,那么我会选择 Raful Chizkiyahu。


我的一个 C# Winforms 程序存在内存泄漏,我想绘制其内存使用情况随时间变化的图表,以便更好地了解可能导致泄漏的原因。问题是,none 的常用内存诊断命令与任务管理器声称为该进程消耗的内存相匹配。我认为这可能是由于使用 unsafe/unmanaged 代码的应用未包含在总数中。

因此,为了尝试更深入地钻研,我创建了一个新的 Winforms 应用程序,非常简单,只有一个计时器来实时报告内存使用情况。我使用了 5 个标签,每个都有不同的功能(主要是 from here):Environment.WorkingSetGC.GetTotalMemory(false)GC.GetTotalMemory(true)Process.GetCurrentProcess().PrivateMemorySize64Process.GetCurrentProcess().WorkingSet64

令人惊讶的是(或者也许不是这样,叹息),我仍然无法将这五个数字中的任何一个与 Windows 10 任务管理器相匹配。这是屏幕截图:

所以我主要寻找的是 5.1MB 的数字。我如何偷偷地从 .NET 框架中提取隐藏的数字?

这是我在计时器滴答函数中的代码:

private void timer1_Tick(object sender, EventArgs e)
{
    //Refresh();
    label1.Text = "Environment.WorkingSet: " +  Environment.WorkingSet ;
    label2.Text = "GC.GetTotalMemory(false): " +    GC.GetTotalMemory(false) ;
    label3.Text = "GC.GetTotalMemory(true): " + GC.GetTotalMemory(true) ;
    Process proc = Process.GetCurrentProcess();
    label4.Text = "proc.PrivateMemorySize64: " +    proc.PrivateMemorySize64 ;
    label5.Text = "proc.WorkingSet64: " +       proc.WorkingSet64 ;
    proc.Dispose();
}

可能很明显,我尝试使用和不使用 Refresh() 命令都无济于事。


编辑:赏金已过期,但如果社区愿意将其奖励给某人,那么我会选择 Raful Chizkiyahu。

任务管理器不提供 "Exact" RAM 使用情况。尝试使用 Visual Studio 的诊断工具或 resourcemonitor

但是,为了获得确切的内存使用情况,我认为这段代码可以工作

using System.Diagnostics;
// This obtains the current application process
Process thisProcess = Process.GetCurrentProcess();

// This obtains the memory used by the process
long usedMemory = thisProcess.PrivateMemorySize64;

// This will display the memory used by your C# app
 label6.Text= System.Convert.ToString(usedMemory)

我假设您的下一个标签是 "label6"。如果您添加了更多标签,请更改它。

希望对您有所帮助:)

编辑:如果将 "usedMemory" 除以 2850023.23,您可以得到一个大约等于任务管理器中显示的内存的值。

// This obtains the current application process
        Process thisProcess = Process.GetCurrentProcess();

        // This obtains the memory used by the process
        long usedMemory = thisProcess.PrivateMemorySize64;

        // 3. This will display the memory used by your C# app
        label6.Text = System.Convert.ToString(usedMemory/ 2850023.23);

您需要更好的工具,TaskManager 只会在特定时刻为您提供大概的内存使用情况。

如果您怀疑内存泄漏,可靠的方法是获取应用程序的内存转储(快照)。

应在应用程序启动时拍摄快照,然后在随后的时间间隔拍摄。如果内存增长缓慢,您将不得不在每次快照之间稍等片刻。然后您可以比较快照。此方法允许您分析和比较对象分配、对象计数,甚至非托管内存。

Microsoft has written a guide for the Memory Usage tool integrated into Visual Studio。在大多数情况下,这足以识别泄漏。

如果您发现集成工具有限,请查看此 SO question 和边栏中链接的其他内容。

windows 任务管理器只显示实际在 RAM 上的内存和进程内存包括页面(在磁盘上) 进程内存可能比机器上的实际 RAM 更大的原因

我注意到 Visual studio 在大多数情况下,调试工具报告的内存使用率高于任务管理器 虽然任务管理器只报告 RAM 的使用情况,但 VS 中的调试工具会考虑页面文件等所有内容...等等

我觉得他们会更靠谱