c# - WinForm 什么时候释放它的资源? (C#)

标签 c# .net winforms

这是一个 C# WinForm 问题。我有一个 MDI 子窗体,当窗体打开时,它会生成许多表以显示在 DataGridView 中。表格可能很大,我使用 DataBinding 将表格连接到 DataGridView。当我关闭表单时,我注意到表单占用的内存被及时回收。

我使用显示 MDI 子窗体的正常方式为:

var f = new FormBigMemory(objPassedIn);
f.Show();

如此处所示,我无法显式调用表单的 Dispose() 方法。我假设当 f 超出其生命周期时,.net 将自动回收它占用的内存。

由于表单占用大量内存,我想显式调用 GC.Collect(); (我知道这样做可能不是一个好主意)。为此,我更改代码以使用以下代码在对话框模型中显示表单:

using(var f = new FormBigMemoryDialog(objPassedIn);
{
    f.ShowDialog();
}

GC.Collect();

看到调用 GC.Collect() 后表单占用的内存没有被回收,我感到非常失望。在关闭表单并调用 GC.Collect() 后,我使用内存分析器工具获取内存快照。最大的内存被一个 BindingList 占用了!实在不明白:如果整个表单都被dispose了,为什么内存中还存在BindingList。我已经检查了我的代码,没有 BindingList 引用从表单中泄露出来的地方。

知道为什么这种有线的事情会发生在我身上吗?非常感谢有关 .net 内存管理的任何建议和技巧。

编辑:

感谢您的回答。让我澄清一些要点。

  1. 我并不是要处置 BindingList。 BindingList 在我的代码中用作数组,因此我希望看到 BindingList 持有的内存的回收。我的不好没说清楚。

  2. 我知道不能自己调用​​ GC 操作。但就我而言,我想在关闭表单后立即明确地看到表单占用的内存回收,无论如何要做到这一点?示例代码?

  3. 在我的问题中,我可以多次重复打开同一个表单,每次关闭表单时,内存消耗都会增加,直到抛出 OutOfMemory。这显然是不对的。我希望看到的是,在关闭表单后,内存会回落到原来的水平,我可以重复打开和关闭表单而不会(显着地)增加内存。

编辑 2:

我进一步研究了代码。最大的数组(一个BindingList)在窗体关闭后不释放。它由 BindingSource 引用,BindingSource 由 EventHandler、CurrencyManager 和用户控件引用。 BindingSource 和用户控件均由(关闭)表单引用,而(关闭)表单由某些事件处理程序引用。

上面是我关闭窗体后的内存快照。我使用对话框模型打开窗体,在关闭窗体后调用其 Dispose() 方法,之后我还调用 GC.Collect() 强制回收内存。为什么在这之后表单实例仍然存在于我的内存快照中??

最佳答案

永远不要调用 GC.Collect,除非你有充分的理由这样做。

我不知道细节,但这是我所知道的:

  • 在删除所有 引用后删除某些内容。
  • GC 不会尝试一次删除所有内容,它不想干扰程序运行。
  • 表单很可能只是隐藏,而不是关闭。你如何关闭表单?
  • 作为Mitch Wheat says , 事件处理程序可能很顽固,因为您经常忘记删除它们。
  • Dispose 不会使表单从内存中删除,它会在表单内部调用一个普通方法,也许您可​​以在其中插入自己的清理逻辑。

关于c# - WinForm 什么时候释放它的资源? (C#),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1113962/

相关文章:

c# - 非管理员帐户的 Report Viewer 2010 问题

c# - 去斑 - 从图像中去除 Blob 或点

c# - 通过接口(interface)创建假对象

c# - Platform.GetRenderer(view) 已过时

.net - ILMerge 和大量 dll 的性能

C# 网络问题多进程

c# - 谓词的委托(delegate)不起作用

c# - Visual Studio 扩展资源文件

c# - 如何提取位于圆括号(圆括号)之间的文本?

c# - 自定义用户控件如何将数据发送到托管表单