Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 stub 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.

like image 529
MZywitza Avatar asked Jun 06 '11 16:06

MZywitza


People also ask

Which method is used to garbage collect an object?

The gc() method is used to invoke the garbage collector to perform cleanup processing. The gc() is found in System and Runtime classes.

When an object is no longer used which method is called automatically by the garbage collector in Java?

Finalization. Before an object gets garbage-collected, the garbage collector gives the object an opportunity to clean up after itself through a call to the object's finalize method. This process is known as finalization.

How does the garbage collector know if an object can be collected?

An object is eligible to be garbage collected if its reference variable is lost from the program during execution. Sometimes they are also called unreachable objects.


2 Answers

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.

like image 134
Patrick Avatar answered Sep 21 '22 02:09

Patrick


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.

like image 22
Sven Avatar answered Sep 21 '22 02:09

Sven