繁体   English   中英

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

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

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


我在我的一个 C# Winforms 程序中有一个 memory 泄漏,我想绘制它的 memory 随着时间推移的使用情况,以便更好地了解可能导致泄漏的原因。 问题是,没有一个常用的 memory 诊断命令与任务管理器声称其为该进程消耗的 memory 相匹配。 我认为这可能是由于使用不安全/非托管代码的应用程序未包含在总数中。

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

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

图片

所以我基本上要找的是那个 5.1MB 的数字。 如何从 .NET 框架中偷偷地提取隐藏的数字?

这是我在计时器刻度 function 中的代码:

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。

The windows task manager is showing only the memory that actually on the RAM and the process memory is including the pages (on the disk ) that the reason the process memory can be bigger from the actual RAM on your machine

任务管理器不会为您提供“准确”的 RAM 使用情况。 尝试使用 Visual Studio 的诊断工具或资源监视器

但是,为了获得准确的 memory 用法,我认为这段代码可以工作

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)

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

希望能帮助到你:)

编辑:如果您将“usedMemory”除以 2850023.23,您可以获得一个大约等于任务管理器中显示的 memory 的值。

// 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);

我注意到在大多数情况下,Visual Studio 调试工具报告的 memory 使用率高于任务管理器,而任务管理器仅报告 RAM 的使用情况,VS 中的调试工具将考虑页面文件等所有内容

我认为他们会更可靠

您需要更好的工具,TaskManager 只会在某个时刻为您提供近似的 memory 使用情况。

如果您怀疑 memory 泄漏,经过验证的正确方法是获取应用程序的 memory 转储(快照)。

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

Microsoft 为集成到 Visual Studio 中的 Memory 使用工具编写了指南 在大多数情况下,这足以识别泄漏。

如果您发现集成工具有限,请查看此SO 问题以及侧边栏中链接的其他问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM