Garbage Collection Unit Test

Unit tests are useful in order to guarantee code works as it is expected to work. Today my spidey sense told me I might have caused a memory leak. Let’s not consider unmanaged code for now, but wouldn’t it be great if you could write a unit test to prove that a particular object can be garbage collected? I found some interesting ideas online, but no reusable solution. What follows is my attempt at an Assert method which can be used during unit testing.

object empty = new object();
AssertHelper.IsGarbageCollected( ref empty );

It works by using a WeakReference, which references an object while still allowing that object to be reclaimed by garbage collection. The object to test is passed using the ref keyword, which allows the Assert method to set it to null. This allows it to be garbage collected.

public static void IsGarbageCollected<TObject>( ref TObject @object )
	where TObject : class
{
	Action<TObject> emptyAction = o => { };
	IsGarbageCollected( ref @object, emptyAction );
}

public static void IsGarbageCollected<TObject>( ref TObject @object, Action<TObject> useObject )
	where TObject : class
{
	if ( typeof( TObject ) == typeof( string ) )
	{
		// Strings are copied by value, and don't leak anyhow.
		return;
	}

	int generation = GC.GetGeneration( @object );
	useObject( @object );
	WeakReference reference = new WeakReference( @object );
	@object = null;

	GC.Collect( generation, GCCollectionMode.Forced );
	GC.WaitForPendingFinalizers();

	Assert.IsFalse( reference.IsAlive );
}

As it turns out I did write a memory leak in the code I wanted to test. 😦 At least I know about it now! As usual, I added the total code and some unit tests to my FCL library.

WARNING: Due to differences when using the Release configuration (I assume compiler optimizations), some of these unit tests will fail. Be sure to run them in Debug!

Advertisements
  1. Aspects and Garbage Collection « Whathecode

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: