神秘数组在单元测试中保持对对象的引用

时间:2015-03-05 22:29:31

标签: c# unit-testing garbage-collection xunit.net

我刚刚在Visual Studio 2013 Update 4中发现了一个非常奇怪的行为。请考虑以下xunit.net测试:

[Fact]
public void TestTargetMustNotHoldAReferenceToItemsAfterCallingClear()
{
    var item = new MarkedType();
    var weakReferenceToItem = new WeakReference<MarkedType>(item);
    var testTarget = new ListBuilder<MarkedType>().WithItems(item)
                                                  .Build();

    testTarget.Clear();

    item = null;
    GC.Collect();
    MarkedType retrievedItem = null;
    Assert.False(weakReferenceToItem.TryGetTarget(out retrievedItem));
    Assert.Null(retrievedItem);
}

public class MarkedType { }

在其中,我想检查我自己的List<T>实现在我调用Clear之后没有对堆上的对象的引用。因此,在调用item之后,我将null设置为Clear,并让垃圾收集器运行,以便它可以释放MarkedType实例。之后我用弱引用检查实例是否真的消失了。

这是奇怪的事情:此测试未通过xunit.net v2.0.0预发行版在VS 2013 Update 4中的调试模式下传递,因为WeakReference.TryGetTarget返回true但是,如果我切换到发布模式,则此测试通过。我还在VS 2015 CTP6中运行了此测试,并在其中传递了两个配置,即调试和发布。

然后我创建了两个内存转储(一个在垃圾收集器运行之前,一个之后)以找出哪个对象在内存中保留item并且我找到了一个未在我的测试中列出的对象数组:

Marked Type Path To Root

我的实际问题是:这个对象数组来自哪里?为什么它不在发布模式(或VS 2015)中出现?我可以以某种方式禁用或绕过它吗?

如果您想使用源代码,可以在github上使用(请使用FailingReferenceTest分支):https://github.com/feO2x/BeginningTdd

0 个答案:

没有答案