Search code examples
c#unit-testingmemory-leaksweak-references.net-4.8

Unit test to detect Memory leaks


According the 8th step of this post I wrote the following simple unit test to make sure my Test class doesn't cause memory leaks:

private class TestClass
{

}
[TestMethod]
public void MemoryLeakTest()
{
   vat testObj = new TestClass();
   var weakRef = new WeakReference(testObj)

   testObj = null;
   GC.Collect();
   GC.WaitForPendingFinalizers();
   GC.Collect();
   Assert.IsFalse(weakRef.IsAlive);
}

The test passes in the master branch of my code repository, but when I run the test in a feature branch, the test fails. So I have two questions:

  1. Is this method reliable to detect memory leaks of my classes?
  2. What conditions can cause this test to pass in one branch and fail in another?

Solution

  • There are very few possibilities where this test would do something useful. All of them would involve that the constructor of Test does some kind of registration on a global variable (either register itself on a global event or store the this pointer in a static member). Since that is something that's very rarely done, doing the above test for all classes is overshooting. Also, the test does not cover the far more typical cases for a memory leak in C#: Building up a data structure (e.g. a List) and never clean it up.

    This test may fail for a number of reasons: GC.Collect() does not necessarily force all garbage to be cleaned. It should, but there's no guarantee that it will always happen. Also, since testObj is a local variable, it is not yet out of scope when you call GC.Collect(), so depending on how the code is optimized, the variable cannot be considered garbage yet, which makes the test fail.