WeakReference的行为当对象最终完成但尚未垃圾回收 [英] WeakReference Behavior When Object Is Finalized But Not Yet Garbage Collected

查看:125
本文介绍了WeakReference的行为当对象最终完成但尚未垃圾回收的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是关于在C#/。NET对象终止和收集一个学术问题。背景阅读是C#语言规范,自动内存管理的第3.9节。



当有一个对象没有明确提及,就可能成为垃圾回收。它成为符合销毁条件。在未来的某个时候(例如,如果你强迫垃圾收集),对象的析构函数将被运行。



在析构函数,如果你一个参考保存的对象,该对象将被最终确定,但是将没有资格领取。这可能导致在它已经完成,但没有收集的状态的对象之中。该规范的3.9节有这样的一个例子。



在这一点上,对象是真的还活着,因为它尚未垃圾回收。然而,一个WeakReference的参照对象报告的假一个的IsAlive值,指示该对象已被收集。



的核心问题是 - 什么是财产的IsAlive真的报告?我们知道,我们不能信任值true此属性,因为该值会你读它之后变成假的。但是false值是值得信赖的,意思是指(根据文档),该对象已被垃圾收集。那么,什么是财产的IsAlive告诉我们,在这种情况下?没有严格的对象是否已经被垃圾回收,因为我们相信,对象是在敲定,但并非集中状态。



下面是一个示例,显示的行为。

 公共类犬
{
公共静态狗KeepDogRef;



公共字符串名称{;组; }

公狗(字符串名称)
{
名称=名称;
}

〜狗()
{
Console.WriteLine(狗析构函数+姓名+称为);
Dog.KeepDogRef =这一点;
}

公共无效树皮()
{
Console.WriteLine(名称+:汪);
}
}

和代码主程序。如果您运行的代码,你会看到,原来的WeakReference报告的IsAlive为假,即使我们重组的对象。

 静态无效的主要()
{
狗狗=新的狗(库巴);

的WeakReference dogRef =新的WeakReference(狗);

// UNREF鲍泽,现在符合销毁
狗= NULL;
GC.Collect的();
GC.WaitForPendingFinalizers();

//鲍泽不再活着
Console.WriteLine(的String.Format(对象还活着:{0},dogRef.IsAlive));

//鲍泽再放
狗newRef = Dog.KeepDogRef;
newRef.Bark();
}
}


解决方案

如果你看所有的文档的 的WeakReference ,很明显,有不止一种类型的弱引用可用。默认值是产生的弱引用。但你也可以创建弱引用其中特别考虑复活的场景



从的 TrackResurrection




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



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




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


Here's an academic question about object finalization and collection in C#/.NET. Background reading is section 3.9 of the C# language spec, Automatic Memory Management.

When there are no explicit references to an object, it may become garbage collected. It becomes "eligible for destruction". At some point in the future (e.g. if you force garbage collection), the object's destructor will be run.

In the destructor, if you save a reference to the object, the object will be finalized, but will not be eligible for collection. This can lead to an object being in a state where it has been finalized, but not collected. Sec 3.9 of the spec has an example of this.

At this point, the object is really still alive, since it has not yet been garbage collected. However, a WeakReference referring to the object reports an IsAlive value of false, indicating that the object has been collected.

The core question is this--what is the IsAlive property really reporting? We know that we can't trust a value of true for this property, because the value can become false shortly after you read it. But a value of false is trustworthy and is meant to indicate (according to documentation) that the object has been garbage collected. So what is the IsAlive property telling us in this case? Not strictly whether the object has been garbage collected, since we believe that the object is in a finalized-but-not-collected state.

Here's a sample to show the behavior.

    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");
    }
}

And code for main program. If you run the code, you'll see that the original WeakReference reports IsAlive as false, even after we reconstitute the object.

    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();   
    }
}

解决方案

If you read all of the documentation for WeakReference, it's clear that there is more than one type of weak reference available. The default is to produce a short weak reference. But you can also create long weak references which specifically account for resurrection scenarios.

From the documentation for TrackResurrection:

Gets an indication whether the object referenced by the current WeakReference object is tracked after it is finalized.

If true, the weak reference is a long weak reference and true was specified for the trackResurrection parameter in the WeakReference constructor.

So I'd say you have to understand this part of weak references before interpreting the IsAlive property.

这篇关于WeakReference的行为当对象最终完成但尚未垃圾回收的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆