WP7 app development lessons learned: Memory optimizations with the help of weak references
Background
Weak references are an easy and effective way to keep your app’s memory usage in order. Wikipedia sums up the idea behind weak references very neatly:
a weak reference is a reference that does not protect the referenced object from collection by a garbage collector. An object referenced only by weak references is considered unreachable (or "weakly reachable") and so may be collected at any time.
Implementation
WP7’s framework contains a System.WeakReference –class which you can use in your application. But keep in mind that you can’t derive from this class because it’s constructor is marked with SecuritySafeCritical-attribute. To get around this limitation and to get a generic version as an added bonus, you can use the following class to implement the WeakReference in your app (I’m sorry but I have lost the original source of the following code):
public class WeakReference<T> { public WeakReference(T target) { reference = new WeakReference(target); } public bool IsAlive { get { return reference.IsAlive; } } public T Target { get { return (T)reference.Target; } set { reference.Target = value; } } }
Usage
Using the class presented above is easy. Here’s an example of a code where we aren’tusing WeakReference yet:
protected WriteableBitmap bitmapImage; public ImageSource ImageSource { get { if (bitmapImage != null) { return bitmapImage; } if (ImageUri != null) ThreadPool.QueueUserWorkItem(DownloadImage, ImageUri); return null; } }
Here’s an updated version where WeakReference is used:
protected WeakReference<WriteableBitmap> bitmapImage; public ImageSource ImageSource { get { if (bitmapImage != null) { if (bitmapImage.IsAlive) { return bitmapImage.Target; } Debug.WriteLine("Source has been garbage collected. Create new."); } if (ImageUri != null) ThreadPool.QueueUserWorkItem(DownloadImage, ImageUri); return null; } }
Benefits
Without using the WeakReference-class, the memory usage of Teletext Finland app looks like this after a couple minutes:
With the updated version, the memory usage is drastically better: