Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I write a unit test to determine whether an object can be garbage collected?

In relation to my previous question, I need to check whether a component that will be instantiated by Castle Windsor, can be garbage collected after my code has finished using it. I have tried the suggestion in the answers from the previous question, but it does not seem to work as expected, at least for my code. So I would like to write a unit test that tests whether a specific object instance can be garbage collected after some of my code has run.

Is that possible to do in a reliable way ?

EDIT

I currently have the following test based on Paul Stovell's answer, which succeeds:

     [TestMethod]     public void ReleaseTest()     {         WindsorContainer container = new WindsorContainer();         container.Kernel.ReleasePolicy = new NoTrackingReleasePolicy();         container.AddComponentWithLifestyle<ReleaseTester>(LifestyleType.Transient);         Assert.AreEqual(0, ReleaseTester.refCount);         var weakRef = new WeakReference(container.Resolve<ReleaseTester>());         Assert.AreEqual(1, ReleaseTester.refCount);         GC.Collect();         GC.WaitForPendingFinalizers();         Assert.AreEqual(0, ReleaseTester.refCount, "Component not released");     }      private class ReleaseTester     {         public static int refCount = 0;          public ReleaseTester()         {             refCount++;         }          ~ReleaseTester()         {             refCount--;         }     } 

Am I right assuming that, based on the test above, I can conclude that Windsor will not leak memory when using the NoTrackingReleasePolicy ?

like image 312
driis Avatar asked Feb 23 '09 19:02

driis


People also ask

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

The garbage collector uses a traversal of the object graph to find the objects that are reachable. Objects that are not reached in this traversal are deemed garbage, even if they are part of a cycle of references.

What is garbage collection in testing?

Garbage collection is the memory management process for objects in the heap. As objects are allocated to the heap, they run through a few collection phases – usually rather quickly as the majority of objects in the heap have short lifespans.

Which method is called just before an object is garbage collected?

It is possible to define a method that will be called just before an object's final destruction by the garbage collector. This method is called finalize( ), and it can be used to ensure that an object terminates cleanly.


2 Answers

This is what I normally do:

[Test] public void MyTest()  {     WeakReference reference;     new Action(() =>      {         var service = new Service();         // Do things with service that might cause a memory leak...          reference = new WeakReference(service, true);     })();      // Service should have gone out of scope about now,      // so the garbage collector can clean it up     GC.Collect();     GC.WaitForPendingFinalizers();      Assert.IsNull(reference.Target); } 

NB: There are very, very few times where you should call GC.Collect() in a production application. But testing for leaks is one example of where it's appropriate.

like image 180
Paul Stovell Avatar answered Sep 21 '22 22:09

Paul Stovell


Perhaps you could hold a WeakReference to it and then check to see that it no longer alive (i.e., !IsAlive) after the tests have completed.

like image 26
denis phillips Avatar answered Sep 19 '22 22:09

denis phillips