将对象保留在GC销毁尝试上

时间:2012-10-11 21:31:21

标签: c# garbage-collection

我在考虑回收物品的方法时得到了这个想法。我这样做是为了看看内存池是如何工作的,我意识到在99%的场景中这是非常不必要的。

但是,我有一个问题。有没有办法强制GC保持对象?换句话说,我可以告诉GC不要销毁一个对象,并说在一个可用于使用对象的列表中创建了新的引用吗?虽然我没有对此进行测试,但问题在于,如果我将这样的内容添加到列表中:

~myObject()
{
     ((List<myObject>)HttpContext.Current.Items[typeof(T).ToString()]).add(this);//Lets assume this is ASP
}

它会将一个指向此对象的指针添加到列表中,但如果该对象被销毁,我将得到一个空指针异常,因为该对象不再存在。但是,也许我可以告诉GC不要收集这个项目,从而保留对象?

我知道这是大多数程序员会选择的东西“你为什么要这样做?”。但另一方面,编程是关于尝试新事物和学习新事物。有什么建议,想法,实施吗?任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:6)

是的,这是合法的。它被称为“复活”。当您将this引用分配给“实时”某处时,该对象不再被视为垃圾。

您还需要使用GC.ReRegisterForFinalize(this)重新注册以进行最终化,或者下次对象变为垃圾时,它将无法完成(不会调用析构函数)。

您可以在this MSDN Magazine article中了解有关对象复活的更多信息。

答案 1 :(得分:2)

是的,这是可能的,它甚至有一个名字:复活。

  

但如果对象被销毁,我将得到一个空指针异常,因为该对象不再存在。

更糟糕的是,你会得到一个无效的指针(引用)错误。可能是蓝屏或崩溃的服务器。但幸运的是CLR不会让这种情况发生。简单地将一个注定的实例放在任何类型的列表中使它再次可以访问,然后它将不会被回收。

当您希望多次回收对象时,您必须在其上调用GC.ReRegisterForFinalize(x)

尽管最实际的答案是:不要这样做。单独的析构函数占了相当大的开销,并且有很多方法可以解决这个问题。

答案 2 :(得分:0)

GC只会处理那些引用已经消失的对象,无论是否超出明确释放的范围。

无论哪种方式,您都需要查看KeepAliveSuppressFinalize方法,以防止GC垃圾收集您的对象。一旦你真正完成它们,你需要注册它们以便收藏家使用ReRegisterForFinalize来接收它们。