【问题标题】:Memory usage in WinformsWinforms 中的内存使用情况
【发布时间】:2011-07-23 12:56:44
【问题描述】:

我有两种形式的非常简单的应用程序(创建用于测试内存)。解决方案有三个项目。第一个有表格,第二个 DAL 和第三个 ComonLib

(所有这些内存数据均来自任务管理器。问题的最后有 4 个内存分析器图像的 url)

当我运行我的应用程序时,内存使用量约为8MB。此表单只有两个按钮。一个按钮是打开第二个表单,另一个按钮是收集GC

当我打开 2nd form 时,内存增加到 550MB 左右。此表单有一个网格,并且数据 (1000s of records) 在 Load 事件中加载到此网格中。

打开第二个表单的代码。

CallWidnows cw = new CallWidnows();
cw.ShowDialog();
cw.Dispose();

第二种形式的加载事件

Customers customers = new Customers();
dataGridView1.DataSource = customers.GetAllCustomers();

第二种形式的关闭事件。

dataGridView1.Dispose();

但是关闭2nd form后内存使用量没有变化,内存使用量还是550MB

等了一分钟左右后,我明确地调用了GC.Collect(),只释放了几MB的内存,变成了530MB

等了一分钟左右后,我再次致电GC.Collect(),现在内存下降到40MB

  • 谁能帮我理解这个 内存使用行为?

  • 为什么要处理表单和网格内存 没有发布?

  • 为什么第二次打电话 GC.Collect()所有内存 释放但在我调用它时没有 第一次?

我的原始应用程序有几十个表单和用户控件,我在这个应用程序中遇到了内存问题。

  • 谁能建议几个步骤 分析 Winforms 应用中的内存使用情况?

一个侧面的问题: 最初我有以下方法作为静态方法。

Customers customers = new Customers();
dataGridView1.DataSource = customers.GetAllCustomers();

就像

// Static GetAllCustomers method
dataGridView1.DataSource = Customers.GetAllCustomers();
  • 在我的原始应用程序中,所有 DAL 方法是静态的。静态方法 可能是内存泄漏的原因 像上面那样使用?

内存分析器图像:

1- Application Starts Memory usage 8MB

2- Second form opens and data loaded - Memory Usage - 550MB

3- Second form closed. Form disposed and grid disposed - Memory Usage still - 550 MB

4- First time GC.Collect called.

谢谢。

【问题讨论】:

标签: c# winforms visual-studio-2008 memory memory-leaks


【解决方案1】:

两次 GC 释放内存是内存在终结器中被清理的标志(例如 COM 对象,任何需要 dispose 清理的东西)。第一次 GC 定位对象,但只安排它们完成。下一个 GC 运行它们。您可以在第一次 GC 之后调用 WaitForPendingFinalizers 来测试这是否为真——那么它不应该需要两次 GC。

对我来说,我使用带有 SOS dll 的 WinDbg 来理解这些问题。您也可以在 VisualStudio 中加载 SOS,但我更喜欢 WinDbg。 SOS dll 让您可以将对象转储到堆上并查看它们为何被植根(即什么对象使它们保持活动状态并需要被释放)。

并非每个人都具有相同的技能,因此可以在此 SO 问题中找到有关查找 .net 泄漏的其他建议:Tool for diagnosing memory leaks in .NET (ASP.NET Application)

【讨论】:

    猜你喜欢
    • 2023-03-12
    • 1970-01-01
    • 2010-10-19
    • 2014-07-31
    • 2012-11-10
    • 2014-07-11
    • 2015-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多