gpt4 book ai didi

c# - 对象完成但尚未收集垃圾时的弱引用行为

转载 作者:太空狗 更新时间:2023-10-29 23:00:44 28 4
gpt4 key购买 nike

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

当没有明确引用某个对象时,它可能会被垃圾回收。它变得“有资格销毁”。在未来的某个时刻(例如,如果您强制进行垃圾回收),对象的析构函数将运行。

在析构函数中,如果保存对象的引用,对象将被终结,但不符合回收条件。这可能导致对象处于已完成但未被收集的状态。规范的第 3.9 节有一个这样的例子。

在这一点上,这个对象真的还活着,因为它还没有被垃圾回收。但是,引用该对象的 WeakReference 报告 IsAlive 值为 false,表明该对象已被收集。

核心问题是——IsAlive 属性真正报告的是什么?我们知道我们不能相信此属性的值为 true,因为该值在您阅读后不久可能会变为 false。但是 false 的值是值得信赖的,并且意味着(根据文档)该对象已被垃圾收集。那么在这种情况下 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 报告为 false,即使在我们重构该对象之后也是如此。

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

最佳答案

如果您阅读了 WeakReference 的所有文档,很明显,有不止一种类型的弱引用可用。默认是生成一个short weak reference。但您也可以创建弱引用,专门说明复活场景。

来自 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.

所以我想说,在解释IsAlive 属性之前,您必须了解弱引用的这一部分。

关于c# - 对象完成但尚未收集垃圾时的弱引用行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13915302/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com