下面是关于C#/。NET对象终止和收集一个学术问题。 背景阅读是C#语言规范,自动内存管理的第3.9节。
当有一个对象没有明确提及,就可能成为垃圾回收。 它成为“符合销毁条件”。 在未来的某个时候(例如,如果你强迫垃圾收集),该对象的析构函数将被运行。
在析构函数,如果你一个参考保存对象,该对象将最终确定,但将不符合回收。 这可能导致在它已经敲定,但没有收集的状态的对象之中。 规范的3.9节有这样的例子。
此时,对象是真的还活着,因为它尚未被垃圾回收。 然而,WeakReference的参照对象报告的假的值的IsAlive,指示该对象已被收集。
核心的问题是 - 什么是IsAlive属性确实报告? 我们知道,我们不能相信的真实的值此属性,因为该值会你读它之后变成假的。 但假值是值得信赖的,意思是指(根据文档),所述对象已被垃圾收集。 那么,什么是IsAlive属性告诉我们在这种情况下? 没有严格的对象是否已被垃圾回收,因为我们相信,对象是在最终确定的但不收集的状态。
下面是一个示例,显示的行为。
public class Dog
{
public static Dog KeepDogRef;
public string Name { get; set; }
public Dog(string name)
{
Name = name;
}
~Dog()
{
Console.WriteLine("Dog destructor for " + Name + " called");
Dog.KeepDogRef = this;
}
public void Bark()
{
Console.WriteLine(Name + " : Woof");
}
}
而对于主要程序代码。 如果您运行的代码,你会发现原来的WeakReference报告的IsAlive为假,即使我们重建的对象。
static void Main()
{
Dog dog = new Dog("Bowser");
WeakReference dogRef = new WeakReference(dog);
// Unref Bowser, now eligible for destruction
dog = null;
GC.Collect();
GC.WaitForPendingFinalizers();
// Bowser no longer alive
Console.WriteLine(string.Format("Object still alive: {0}", dogRef.IsAlive));
// Bowser alive again
Dog newRef = Dog.KeepDogRef;
newRef.Bark();
}
}