繁体   English   中英

奇怪的C#弱引用行为

[英]Strange C# Weak Reference Behaviour

我花了一些时间来学习弱引用在C#中是如何工作的,我遇到了这种奇怪的行为。

在下面的示例代码中,第一个测试通过,第二个测试失败。 看起来你不能在构造之后但在创建对它的弱引用之前修改对象的实例,而不是以预期的方式停止弱引用。

private class Simple
{
    public Simple() { X = "Hello"; }
    public string X { get; set; }
}

[Test]
public void CreatingWeakReferenceBeforeModifying()
{
    var a = new Simple();
    var aRef = new WeakReference(a);
    a.X = "World";  // First modification to a after creating reference
    a = null;
    GC.Collect();
    Assert.That(aRef.IsAlive, Is.False);  // This assertion passes
}

[Test]
public void CreatingWeakReferenceAfterModifying()
{
    var b = new Simple {X = "World"};  // First mod to b before creating ref
    var bRef = new WeakReference(b);
    b = null;
    GC.Collect();
    Assert.That(bRef.IsAlive, Is.False);  // This assertion fails
}

我错过了什么吗?

怀疑你在某些情况下只能看到这一点 - 特别是在调试版本下,特别是在调试器下。

这个说法:

var b = new Simple {X = "World"};

有效地:

var tmp = new Simple();
tmp.X = "World";
var b = tmp;

因此,即使您将b设置为null,堆栈上仍然存在一个局部变量,该变量具有对象的引用。

当在优化的场景中运行时,我希望GC注意到局部变量永远不会被再次读取 ,并将其忽略为GC根 - 但可能你运行它的方式不是让GC成为那个侵略性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM