Guillaume86
Guillaume86

Reputation: 14400

How to force full garbage collection in .NET 4.x?

I've a problem with WeakReferences in .NET 4.x, I was running tests to make sure some objects were not referenced anymore (using WeakReferences) and I noticed the behavior is not consistent across framework versions:

using System;
using System.Text;
using NUnit.Framework;

[TestFixture]
public class WeakReferenceTests
{
    [Test]
    public void TestWeakReferenceIsDisposed()
    {
        WeakReference weakRef = new WeakReference(new StringBuilder("Hello"));

        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.WaitForFullGCComplete();
        GC.Collect();

        var retrievedSb = weakRef.Target as StringBuilder;
        Assert.That(retrievedSb, Is.Null);
    }
}

Results:

.NET 2.0  PASS
.NET 3.0  FAIL
.NET 3.5  PASS
.NET 4.0  FAIL
.NET 4.5  FAIL

Is this documented somewhere?

Is there a way to force the GC to collect that reference in .NET 4.5?

Thanks in advance.

Upvotes: 10

Views: 7633

Answers (2)

Cody Gray
Cody Gray

Reputation: 244732

The problem here is related to NCrunch. The code works fine on my machine for all versions of the framework if I replace the test with a simple call to Debug.Assert:

using System;
using System.Text;
using System.Diagnostics;

public class WeakReferenceTests
{
    public void TestWeakReferenceIsDisposed()
    {
        WeakReference weakRef = new WeakReference(new StringBuilder("Hello"));

        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.WaitForFullGCComplete();
        GC.Collect();

        var retrievedSb = weakRef.Target as StringBuilder;
        Debug.Assert(retrievedSb == null);
    }
}

Upvotes: 8

Guillaume86
Guillaume86

Reputation: 14400

Thanks to @ Cody Gray (see comments), I figured that out.

I use NCrunch to run my tests and it was instrumenting the output assembly, producing this behavior (disabling output instrumenting make the test pass on all platforms).

Upvotes: 0

Related Questions