【问题标题】:Dynamic controls memory leak动态控制内存泄漏
【发布时间】:2016-07-13 13:58:11
【问题描述】:

我有一个 Windows 窗体应用程序。当我动态地将一些按钮添加到表单中,然后删除这些按钮时,就会出现内存泄漏。

public partial class Form1 : Form
{
    private Button[] buttons = new Button[1000];

    private void button1_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < 1000; i++)
        {
            var b = new Button();
            Controls.Add(b);
            buttons[i] = b;
        }

        for (int i = 0; i < 1000; i++)
        {
            Controls.Remove(buttons[i]);
            buttons[i].Dispose();
            buttons[i] = null;
        }
    }
}

内存使用情况:

  • 表单加载后:3720 KB
  • 点击按钮 1 后:5144 KB

(这些数字是在执行完整的垃圾回收后记录的。程序在没有调试器的情况下运行,发布版本。)

更奇怪的是,无论 button1_Click 执行多少次,内存使用量都保持在 5100 KB 左右。我做错了什么?

【问题讨论】:

  • 如果内存保持在 5.1 mb,则没有内存泄漏。泄漏通常意味着它不会在某个点停止。
  • 您可以尝试拨打GC.Collect()。另外,请尝试使用 memory 分析器,例如 ANTS Memory Profiler
  • 您从哪里获得使用次数?即使当前未使用应用程序,应用程序也会保留内存,直到操作系统将其取回。
  • 既然你没有提到,如何你测量内存使用量,我猜你只是看看任务管理器。对我来说,这是一种完全不切实际(阅读:幼稚)的方法。取消内存分析器或至少一些性能计数器应该是要走的路。
  • 应用程序不会实时释放内存。如果它们保留一些额外的内存以供将来使用,这对您的操作系统来说很好。当应用程序的内存使用量随着时间的推移超过必要的增长并且当操作系统要求它时无法释放额外的内存时,我们谈论内存泄漏。看看 SQL Server,它会随着时间的推移吃掉所有可用内存,并且只会在 Windows 为另一个进程请求可用内存时才会减少。这并不意味着您每天都需要为您的服务器购买新的 RAM...

标签: c# .net winforms memory-leaks


【解决方案1】:

这不是内存泄漏。首先,如果您为此依赖 Windows 任务管理器,那是不对的。如果您真的想测量应用程序的实际内存,请尝试使用一些性能计数器。或者甚至可能是这样的,

private Process currentProcess = System.Diagnostics.Process.GetCurrentProcess();
long totalBytesOfMemoryUsed = currentProcess.WorkingSet64;

其次,即使在堆中分配的对象被垃圾收集器收集,在它们被释放后,这并不意味着应用程序会释放未分配的内存。只有当操作系统请求有线内存进行其他操作时,才会发生这种情况。底线是,这不是内存泄漏。

【讨论】:

    猜你喜欢
    • 2013-12-29
    • 2023-03-25
    • 2012-07-30
    • 2012-11-16
    • 1970-01-01
    • 2016-12-11
    • 2017-08-11
    • 1970-01-01
    • 2016-08-29
    相关资源
    最近更新 更多