iOS — Identifying Memory Leaks using the Xcode Memory Graph Debugger

April 20, 2017
xcode ios

In this short post I describe,

  • What the Xcode memory graph debugger is

  • How to use it, and some tips

  • It’s pros/cons


What is it

TL;DR: In one sentence, the memory graph debugger helps to answer the following question: Why does an object exist in memory?

The Xcode memory graph debugger helps find and fix retain cycles and leaked memory. When activated, it pauses app execution, and displays objects currently on the heap, along with their relationships and what references are keeping them alive.


How to use it

3 quick steps to identifying retain cycles and memory leaks:

  • 1. Opt in to stack logging integration via the Xcode scheme editor, as follows:

EnablingMallocLogging

Note that we only enable logging of ‘Live Allocations’. This has a lower overhead than ‘All Allocations’ when debugging, and is all we need to identify retain cycles and leaks.

  • 2. Perform whatever app actions you want to analyse (the actions you suspect are causing retain cycles and leaks), and enter memory graph debugging mode by selecting its debug bar button:

Thememorygraphdebuggingbutton

  • 3. The memory graph debugger pauses app execution and displays the following:

Xcodememorygraphdebuggingmode

On the left, the debug navigator displays the app’s heap contents

Selecting a type/instance from the debug navigator shows the instances references in the centre pane

Selecting an instance in the centre reference pane displays general object memory information and the allocation backtrace in the right-hand inspector pane

Leaks are displayed in the debug navigator as follows:

Leaksdisplayedinthedebugnavigator


Tips

  • To help identify memory leaks, we can filter the heap contents to only show leaks using the following:

Filteringformemoryleaks

  • The runtime issue navigator is also useful, displaying the total number of leaks identified:

Lotsof(apparent)memoryleaks!


The good and the bad

  • Good: We can get lucky and find some easy to identify leaks (simple retain cycles). For example — An object capturing itself in a closure property. This is easily fixed using a closure capture list to weakly capture the reference.

  • Bad: False positives (is it a leak?). For example — When creating a UIButton object and adding it to a UIToolBars items array, we have seen it identified as a memory leak but we fail to see why.



That’s it! 📱🚀👍🏽