为什么该弱引用测试失败?

时间:2020-07-01 01:49:36

标签: c# weak-references

探索弱引用,我编写了以下测试以验证我的理解,但测试失败。

据我所知,第一行中没有对object进行“更新”的引用(由WeakReference实例创建的引用除外),请提出问题,为什么weakRef认为Target仍然存在?

我想念什么?为什么测试失败,并且仍然保持对object的引用?

[TestMethod]
public void WeakReference()
{
    var weakRef = new WeakReference(new object(), false);
    GC.Collect();
    GC.WaitForPendingFinalizers();
    Assert.IsFalse(weakRef.IsAlive);
    Assert.IsNull(weakRef.Target);
}

1 个答案:

答案 0 :(得分:3)

我可以使用普通程序(而不是在mstest中运行)复制您的结果。

如果我在未优化的版本中运行以下命令,则会显示:“ Alive:true”。

    private static void Main()
    {
        WeakReference weakRef = new WeakReference( new object(), false );

        GC.Collect( GC.MaxGeneration, GCCollectionMode.Forced, true, true );
        GC.WaitForPendingFinalizers();

        // Prints true in debug, false in release.
        Console.WriteLine( "Alive: " + weakRef.IsAlive );
    }

如果我在启用优化的情况下进行编译,则它可以工作,并显示“ Alive:false”。

另外,如果我将WeakReference的初始化提取到单独的方法中,则无论优化如何,它都可以工作:

    private static void Main()
    {
        WeakReference weakRef = Init();

        GC.Collect( GC.MaxGeneration, GCCollectionMode.Forced, true, true );
        GC.WaitForPendingFinalizers();

        // Always prints false.
        Console.WriteLine( "Alive: " + weakRef.IsAlive );
    }

    private static WeakReference Init()
    {
        return new WeakReference( new object(), false );
    }

说实话,我不确定原因。我的一个假设是,由于缺乏优化,临时对象被存储在堆栈中的隐藏临时变量中。但是,这没有意义,因为GC能够检查堆栈以确定何时最后一次引用了任何变量-只要不使用GC,GC便可以收集当前正在运行的函数中的内容不再。