c# – 垃圾收集应该删除对象,但WeakReference.IsAlive仍然返回true

c# – 垃圾收集应该删除对象,但WeakReference.IsAlive仍然返回true,第1张

概述我有一个测试,我预计通过,但垃圾收集器的行为不是我推测的: [Test]public void WeakReferenceTest2(){ var obj = new object(); var wRef = new WeakReference(obj); wRef.IsAlive.Should().BeTrue(); //passes GC.Collect 我有一个测试,我预计通过,但垃圾收集器的行为不是我推测的:
[Test]public voID WeakReferenceTest2(){    var obj = new object();    var wRef = new WeakReference(obj);    wRef.IsAlive.Should().BeTrue(); //passes    GC.Collect();    wRef.IsAlive.Should().BeTrue(); //passes    obj = null;    GC.Collect();    wRef.IsAlive.Should().BeFalse(); //fails}

在这个例子中,obj对象应为GC’d,因此我希望WeakReference.IsAlive属性返回false.

看来,因为obj变量被声明在与GC.Collect相同的范围内,所以它没有被收集.如果我将对象声明和初始化移动到测试通过的方法之外.

有没有人有任何技术参考文献或解释这个行为?

解决方法 遇到同样的问题,我的测试通过无处不在,除了NCrunch之外(可能是您的情况下的任何其他工具).嗯.使用SOS进行调试会在测试方法的调用堆栈上显示额外的根.我的猜测是,它们是禁用任何编译器优化的代码工具的结果,包括正确计算对象可达性的编译器优化.

这里的治疗是非常简单的 – 从来没有强调GC的方法和对活性的测试.这可以通过简单的帮助方法轻松实现.以下更改使您的测试用例与NCrunch通过,最初出现故障.

[TestMethod]public voID WeakReferenceTest2(){    var wRef2 = CallinItsOwnScope(() =>    {        var obj = new object();        var wRef = new WeakReference(obj);        wRef.IsAlive.Should().BeTrue(); //passes        GC.Collect();        wRef.IsAlive.Should().BeTrue(); //passes        return wRef;    });    GC.Collect();    wRef2.IsAlive.Should().BeFalse(); //used to fail,Now passes}private T CallinItsOwnScope<T>(Func<T> getter){    return getter();}
总结

以上是内存溢出为你收集整理的c# – 垃圾收集应该删除对象,但WeakReference.IsAlive仍然返回true全部内容,希望文章能够帮你解决c# – 垃圾收集应该删除对象,但WeakReference.IsAlive仍然返回true所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1241597.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存