How to prevent Memory and Performance pitfalls on xamarin

Mobile devices have restricted resources compared to desktop or servers: smaller CPU, lower RAM, limited connectivity... Today, I wanted to address concerns about memory management on mobile devices. I get asked a lot by questions from junior and seasoned developers alike, about OOM (out of memory) exceptions, memory leaks and slow downs.

Out of memory exceptions occur when your app needs to allocate more object but the Heap is full. Memory leaks occur when objects are allocated in memory but the Garbage collector (GC) is not able to collect these objects because some live objects hold references to them. Finally slow downs (or lagging) can occur when the Heap is full and the Garbage collector incessantly tries to free up memory which can hog the UI thread.

Today I wanted to share some best practices that I leaned throughout the years developing mobile applications.

1. Reduce file sizes

This is the most common way of getting yourself quickly out of memory. Let’s say you have a splash screen that uses very high res images, (over 100s of megabytes) and additionally you open these giant PDF files in memory and you have these screen rendering tons of images that are also very high res. Soon enough you will end up with no memory left for you to allocate objects that support to business logic and you get OOM exceptions. I recommend checking the size of the files that you load in memory, and if you need to open large files, make sure that those are disposed when you don’t need them anymore.

2. Avoid cyclic references

I am not going in detail about explaining weak references. There are a tons of good resources on the web. iOS uses ARC to count the number of references to a given object in order to know if that objects can be collected. Additionally, Xamarin provides Garbage collector, that live on top of ARC that also free up objects when these are not strongly referenced by other objects. Freeing references to objects can become overwhelming and hard to do in the long run. Thankfully, .Net exposes the type WeakReference that allows you to reference objects in a “Weak“ manner. Thus, objects referenced can still get collected.

3. Unhook your event handlers

EventHandlers can prevent objects from getting garbage collected.

Button.TouchUpInside += (s, e) => {
  this.ShowAlert("...");
}

In the code above, because “this” is referenced in the lambda, it will be hold in memory. Additionally if Button is referenced by This, you get a cyclic reference which means either object will never get collected resulting in a memory leak.

To prevent this, start by always using a method vs lambda expressions and if you really need/want to use lambdas then use WeakReferences for instance objects within it.

Button.TouchUpInside += DoHandleButtonTouch;
Button.TouchUpInside -= DoHandleButtonTouch; 

private void DoHandlerEvent(Object sender, EventArgs e)
{
//dosomething
}

A good pattern that I have applied throughout the years is to hookup events in ViewDidAppear (OnCreate for Android) and unhook these event in ViewWillDisapear (OnDestroy).

If you have additional best practices, please free to share in the comments :)

Happy coding :)