开发者

Garbage collector won't collect an object created with using

I want to test for object references held improperly and wrote a test that always failed. I simplified the test to the following behaviour:

    [Test]
    public void ScopesAreNotLeaking()
    {
        WeakReference weakRef;
        Stub scope = null;
        using (scope = new Stub())
        {
            weakRef = new WeakReference(scope);
        }
        scope = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
        Assert.That(weakRef.Target, Is.Null);
    }

This test however, which does the same without using, passes:

    [Test]
    public void ScopesAreNotLeaking()
    {
        WeakReference weakRef;
        Stub scope = new Stub();
        weakRef = new WeakReference(scope);
        scope = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
        Assert.That(weakRef.Target, Is.Null);
    }

The used s开发者_如何学编程tub class is simple enough:

class Stub : IDisposable
{
    public void Dispose()  {}
}

Can someone please explain me that behaviour or - even better - has an idea how to make sure that the object gets garbage collected?

PS: Bear with me if a similar question was asked before. I only examined those questions that have using in the title.


using is not designed to force garbage collection but to ensure dispose is called. Dispose allows you to release non-garbage collected resources like file handles. Garbage collection happens when c# is good and ready.


I suspect there may be a local introduced by the using statement. Use ildasm to see if all the references in the function to the object are truly cleared before the call to GC.Collect. Also try to put the using bit in a separate function that returns the weak reference.


Your two test cases are not identical. At the end of a using statement, the resource's Dispose method is called, it is not set to null. Calling Dispose does not necessarily call the destructor.


The mark & sweep GC, like it is used in .NET, is not deterministic. Even if called by GC.Collect() there is no guarantee that is really runs.

Additionally, the using-clause does not have anything to do with garbage collection. If just calls Dispose() on its target object.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜