Tracking Dangling Object References In Silverlight
Posted by Davy Brion on August 4th, 2009
One of the downsides of working with a young platform like Silverlight is that the tool support isn’t quite ‘there’ yet, particularly when it comes to profiling for performance and memory usage. And as you may or may not know, Silverlight makes it very easy to introduce memory leaks into your code. Since you can’t just attach a memory profiler to your Silverlight application, optimizing memory usage or tracking down a leak can be a real pain in the ass.
In the past i have resorted to grabbing a memory dump of the browser and analyzing the content of the managed heap with windbg to track down which instances where being kept in memory. While this works, it’s pretty time consuming and can quite easily lead you down the wrong path. One of the most important things that you want to know in this specific case is: which types are being kept in memory, and how many of them?
In this case, being able to query something during debugging regarding which instances are still kept alive in memory at certain times is sufficient for me. So i came up with the following class:
public static class ObjectTracker
{
private static readonly object monitor = new object();
private static readonly List<WeakReference> objects = new List<WeakReference>();
private static bool? shouldTrack;
public static void Track(object objectToTrack)
{
if (ShouldTrack())
{
lock (monitor)
{
objects.Add(new WeakReference(objectToTrack));
}
}
}
private static bool ShouldTrack()
{
if (shouldTrack == null)
{
shouldTrack = Debugger.IsAttached;
}
return shouldTrack.Value;
}
public static IEnumerable<object> GetAllLiveTrackedObjects()
{
lock (monitor)
{
GC.Collect();
return objects.Where(o => o.IsAlive).Select(o => o.Target);
}
}
}
The idea is basically to just keep a list of WeakReferences of objects you want to track (only if a debugger is attached), and later on you can ‘query’ the live instances through the GetAllLiveTrackedObjects method. This method obviously performs a full garbage collect to make sure only objects that are really still alive are returned. Again, you should almost never do a GC.Collect() manually, but in this case the method will only be called while you’re debugging.
Then, you strategically put the following line in the constructor of every kind of type you’d like to track:
ObjectTracker.Track(this);
I have that line in the constructor of my base View class, my base Controller class and in my base Disposable class. So now, when i want to check if there are any dangling references to instances of types that i really don’t want hanging around, i can just do something like this:
var liveObjects = ObjectTracker.GetAllLiveTrackedObjects();
if (Debugger.IsAttached)
{
Debugger.Break();
}
And then manually inspect the content of the liveObjects collection. It’s far from perfect, but at least it’s an easy way to at least know which instances (that i care about) are being kept in memory. It’ll do until we get better tool support :p
August 5th, 2009 at 12:25 pm
[...] Tracking Dangling Object References In Silverlight – Davy Brion shares a technique for tracking the objects you create to help identify dangling object references in Silverlight, although the concepts apply anywhere [...]
August 10th, 2009 at 10:12 pm
[...] Tracking Dangling Object References In Silverlight [...]
August 14th, 2009 at 4:06 pm
Inventive debug tool!
Side note: Although you made effort to synchronize the code, it seems that your code is not fully synchronized. The shouldTrack var in the ShouldTrack method can be initialized multiple times as long as the call is to Debugger.IsAttached not returned. Something you try to prevent by storing the value in a nullable field. You could use a double lock here to prevent this.
August 18th, 2009 at 7:04 pm
[...] er dan? Ik werk zelf niet met silverlight dus is altijd interessant om op de hoogte te zijn. Tracking Dangling Object References In Silverlight | The Inquisitive Coder – Davy Brion’… Finding Memory Leaks In Silverlight With WinDbg | The Inquisitive Coder – Davy Brion’s [...]