探索弱引用,我编写了以下测试以验证我的理解,但测试失败。
据我所知,第一行中没有对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);
}
答案 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便可以收集当前正在运行的函数中的内容不再。