Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 562
Guillaume86 Avatar asked May 27 '13 10:05

Guillaume86


People also ask

Can you force garbage collection in C#?

You can force garbage collection either to all the three generations or to a specific generation using the GC. Collect() method. The GC. Collect() method is overloaded -- you can call it without any parameters or even by passing the generation number you would like to the garbage collector to collect.

Can garbage collection be forced in net?

GC. Collect() Method : Garbage collection can be forced in the system using the GC. Collect() method.

How do I force garbage collection in Visual Studio?

To force a garbage collection, use the hotkey: Ctrl+Alt+Shift+F12, Ctrl+Alt+Shift+F12 (press it twice). If forcing garbage collection reliably makes your scenario work, file a report through the Visual Studio feedback tool as this behavior is likely to be a bug.


1 Answers

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);
    }
}
like image 56
Cody Gray Avatar answered Sep 28 '22 10:09

Cody Gray