在我的程序中,我有一个服务对象,它保持对对象的弱引用。我有一个自动测试,它断言当所有对对象的引用被删除时,弱引用就会被释放。测试的目的是证明当对象没有理由被保存在内存中时,服务不会导致对象留在内存中。
下面是该测试的简化版本:
[Test]
public void WeakReference()
{
var o = Allocate();
var reference = new WeakReference(o.Value);
Assert.IsTrue(reference.IsAlive);
o.Value = null;
GC.Collect();
Assert.IsFalse(reference.IsAlive);
}
private MyObject Allocate()
{
return new MyObject
{
Value = new object()
};
}
private class MyObject
{
public object Value { get; set; }
}在.NET 4.8 NUnit测试项目中,此测试通过。但是,在项目的当前分支中,我在.NET 5项目中进行了测试。在该项目中,由于弱引用保持“活动”,相同的测试代码会失败。
我还尝试将GC.Collect()调用更改为
GC.Collect(int.MaxValue, GCCollectionMode.Forced, blocking: true);没有骰子。
在.NET 5中垃圾收集的工作方式是否发生了根本性的变化,使上述代码不再工作?如何才能仍然证明我的服务对象没有保存在内存中的对象?
发布于 2021-08-18 17:10:30
在以下三种情况下,我能够让你的考试通过:
IsAlive.
此修改后的测试代码演示了上面第1段中提到的循环,并多次重复测试。对我来说总是如此。
[Test, Repeat(1000)]
public void WeakReference()
{
var o = Allocate();
var reference = new WeakReference(o.Value);
Assert.IsTrue(reference.IsAlive);
o.Value = null;
for (var i = 0; i < 2 && reference.IsAlive; i++)
GC.Collect();
Assert.IsFalse(reference.IsAlive);
}我还没有足够的知识来解释为什么会这样做,但我已经发现,这与导致对象引用成为GC根的条件有关(始终是可访问的,而不是GC可收集的)。
https://stackoverflow.com/questions/68079430
复制相似问题