WeakReference的行为当对象被最终确定,但尚未垃圾回收(WeakReference Beh

2019-08-04 04:45发布

下面是关于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();   
    }
}

Answer 1:

如果你阅读所有的文档WeakReference ,很明显,有不止一种类型的弱引用可用。 默认值是产生一个弱引用。 但你也可以创建弱引用其具体解释复活的情景。

从文档TrackResurrection

获取的指示它被最终确定后由当前的WeakReference对象引用的对象是否被跟踪。

如果为true,弱引用是一个长期的弱引用,为指定真trackResurrection在参数WeakReference构造。

所以我说你有解释之前了解弱引用的这部分IsAlive属性。



文章来源: WeakReference Behavior When Object Is Finalized But Not Yet Garbage Collected