0

I have a kind of interesting scenario which exceeds my current knowledge. I would expect the following test to succeed, however, it fails unless I force a manual GC.Collect.

public class Foo : IDisposable {
    public void Dispose() {
        Debug.WriteLine("Disposed.");
    }
}

[Test]
public void CallScopeTest2()
{
    var list = new List<WeakReference>();
    for (var i = 0; i != 5; ++i)
    {
        list.Add(RunInner());
        // give time to GC
        Thread.Sleep(4000);
    }
    //GC.Collect(); // <--- if I uncomment this line, it will collect my objects and test passes

    // give yet a little more time to GC
    Thread.Sleep(5000);

    var c = list.Count(e => e.IsAlive);
    // here c == 5, unless I use the manual collect above
    c.ShouldEqual(0);
}

private static WeakReference RunInner()
{
    WeakReference result;
    using (var foo = new Foo())
    {
        result = new WeakReference(foo);
    }
    return result;
}
Zoltán Tamási
  • 12,249
  • 8
  • 65
  • 93

1 Answers1

1

The GC does not run on a timer, it runs on memory pressure. You do not have enough objects in memory to automaticly trigger a GC, that is why it is not happening.

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
  • Thank you for the clarification, I only knew that it's not deterministic, didn't think that it starts only on memory pressure. Indeed it works, as I modified the code to initialize a large int array in Foo constructor, and played around with loop cycle number.it suddenly started to collect the objects. Actually there is a memory leak in my code which I thought is caused by this behavior. – Zoltán Tamási Feb 03 '16 at 18:00