【问题标题】:Dotnet garbage collector点网垃圾收集器
【发布时间】:2019-12-28 10:31:56
【问题描述】:

我有一个 dotnet 应用程序,我发现它在内存方面一直在增长,然后我决定从这段代码开始做一些测试

Form f0 =null;
using(Form f1 = new Form())
{
   f0=f1;
   f0.Text="Hellow!";
   f0.ShowDialog();
}

f0.Text="Hellow, you here me";// exception attempt here but nothing happens.

这是我的第一个问题。

第二个: 当我在表单内(并在此表单中创建)有 DataGridView 之类的控件时,默认标记为私有;假设我将其更改为公开的,我想从外部(来自表单)帮助程序初始化列,它会改变垃圾收集器的方式吗?

【问题讨论】:

  • 你的代码不会编译
  • 对不起'表格'
  • 一个好习惯是查看IsHandleCreatedIsDisposed(.Net源代码中一直使用前者)。控件不需要是public 才能从拥有它的类外部访问:无论如何,您都可以以不同的方式将其引用传递给另一个类。

标签: c# .net winforms garbage-collection


【解决方案1】:

处置一个对象并不意味着它在垃圾收集方面会突然变得不可访问。在您保留对此类对象的引用之前,GC 将对其进行跟踪。

因此,即使您的表单位于 using 块的末尾,您仍然可以通过您分配的 f0 引用访问它。看来,您可以设置已处理的Form 的一些公共属性,但在using 块之外尝试f0.ShowDialog,您将获得ObjectDisposedException

至于第二个问题:没有代码很难说什么。但尽量不要在一篇文章中混合多个问题。对您的通用问题的通用答案:不要保留从帮助程序类到创建的实例的任何引用,您会没事的。

【讨论】:

  • 其实只要f0存在,或者不设置f0=null,都会阻止垃圾回收。 Disposing 实际上是一个为释放不由 GC 维护的资源(非托管资源)而发明的过程。尽管它今天也用于其他清理过程。但这是清理 - 而不是破坏。
【解决方案2】:

第 1 部分: f0=f1; 表示您保留了对表单对象的引用。

Form.Dispose(在using 块的末尾调用)不会完全破坏表单对象。它释放某些非托管资源(如窗口和控制句柄等),但运行时对象(如Form)在内存中仍然存在。 这些对象被标记为ready to be garbage collected,但 GC 不会立即销毁它们。

这就是为什么f0.Text="Hellow, you here me" 运算符在using 之后没有空引用异常的原因。

但是在using 之后的f0.Show() 将失败并显示object disposed exception

第 2 部分: GC 计算对象引用,因此您使用的帮助程序不应破坏 GC,直到它们保留实例上的引用

class Helper
{
public void AddColumn(Grid grid, string name)
{
 grid.Columns.Add(new GridColumn(name));
}
}

这不会在 grid 或 gridcolumn 实例上存储引用,因此 GC 不受影响

【讨论】:

    猜你喜欢
    • 2018-12-30
    • 1970-01-01
    • 2012-01-18
    • 1970-01-01
    • 2011-11-07
    • 2013-04-01
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多