. net中的对象处理

本文关键字:处理 对象 net | 更新日期: 2023-09-27 18:02:32

假设我有以下类:

Class MainClass
{
   private OtherClass1;
   MainClass()
   {
      OtherClass1 = new OtherClass1();
   }
   void dispose()
   {
      OtherClass1 = null;
   }
}
class OtherClass1
{
   private OtherClass2;
   OtherClass1()
   {
      OtherClass2 = new OtherClass2();
   }
}
class OtherClass2
{
}

如果我实例化MainClass并稍后调用dispose方法,OtherClass1是否获得垃圾收集(稍后)?还是我必须先清除对OtherClass2的引用?

. net中的对象处理

如果一个对象没有引用,或者它的引用来自本身没有引用的对象(以此类推),则该对象将被垃圾收集。

一种可视化的方法是,垃圾收集器将遍历对象引用图,跟踪所有对象引用,并记录它到达的对象(仍然从某处引用)。任何它没有得到的东西都有资格被垃圾收集,因为如果它没有得到它们,那么它们就不可能被使用。

查看这里的深入信息(特别是"垃圾收集算法"):http://msdn.microsoft.com/en-us/magazine/bb985010.aspx

所以是的,它将有资格被GC。


另外,如果你有一个处置方法,你真的应该实现IDisposable

在提供的代码中,您不需要null任何东西,您可以安全地删除您的dispose(),一切都会很好。

如果你的OtherClass1和/或OtherClass2是管理资源,即它们实现IDisposable接口,那么你的代码不够好。然后,您必须链接Dispose:

class MainClass : IDisposable
{
   private OtherClass1;
   MainClass()
   {
      OtherClass1 = new OtherClass1();
   }
   public void Dispose()
   {
      OtherClass1.Dispose(); 
      // OtherClass1 = null;  // not needed
   }
}

如果没有其他引用它,它可能在某个时候被垃圾收集。请注意,这是不是确定性的,您不能依赖于在特定的时间范围内收集它。

一般来说,你不应该太担心这个,. net中的GC可以通过设计处理循环引用等而没有任何问题。通常不需要将字段设置为nullDispose方法通常用于以确定性方式释放非托管资源,例如数据库连接等;

最佳实践是实现IDisposable接口并实现Dispose()方法。

在Dispose()中,你只是释放你的对象所使用的资源,如任何外部资源,COM引用,数据库连接等。

就对象何时被垃圾收集而言,这取决于。net引擎,因为他们经常在每次发布时更新他们的处理算法。

一般来说,当一个对象是孤儿对象(没有变量引用它)时,它将在等待垃圾收集的队列中。

你可以手动调用GC.Collect();但不建议这样做,因为它会干扰。net垃圾收集机制。

术语"Dispose"有点用词不当,因为Dispose方法不删除目标对象,而是为目标对象提供一个请求,让它做任何在安全放弃目标对象之前需要做的事情。从本质上讲,它是请求对象将其事务按顺序排列。

当一个特定的对象需要对其事务进行排序时,最常见的情况是当它外部的一些实体可能正在做某事、存储某事、不做某事或以其他方式临时改变它们代表它的行为时。请注意,实体可以是。net对象,其他类型的os识别对象(GDI句柄等)等,但没有特别要求实体是任何特定类型的东西,也不是它们在同一台计算机中,甚至是任何一台计算机。对于一个对象来说,为了使它的事务井然有序,外部实体代表它做、持有等任何事情都需要被告知它们不再需要这样做。如果有问题的实体是实现了IDisposable的。net对象,则通常通过调用它们的Dispose方法来执行通知。

请注意,.net提供了一种方法,如果系统注意到对象被抛弃了,对象可以请求得到通知,并将其作为一个线索来处理它们的事务。这样的通知可能不会及时出现,而且各种因素可能会导致它们基本上无限期地延迟,但这种机制(称为"终结")有时总比没有好。