How do you use Instruments’ Allocations, Leaks and VM Tracker to track a memory problem?

3.7.3 · L5 · Interview

Predict first

You mark a generation after each of 5 visits to a screen. What indicates a leak or abandoned memory?

// A: transient allocations in each generation
// B: persistent allocations that grow in every generation
// C: a high total at the start
  • A
  • B
  • C

Mental model. Marking a generation is chalking a line on the wall. After each visit anything new above the line that is still there belongs to that visit.

Allocations records every allocation with its call stack. The method that finds growth is generations: take a baseline, repeat the action (open and close a screen), press Mark Generation, and repeat a few times. Each generation shows the allocations that were created in it and are still alive. A healthy flow shows roughly nothing persistent per generation; a leak or abandoned memory shows the same growth every time, and its stack trace shows where it came from. “Transient” allocations that died are not the problem; “persistent” ones are.

Leaks periodically scans for unreachable memory and reports cycles. VM Tracker shows memory by region and state (dirty, resident, swapped): it explains big footprints that Allocations cannot, such as decoded images and graphics memory. Time Profiler shows the CPU cost of retain and release. Always profile a Release build on a real device, because memory behaviour and optimisation differ from the simulator and Debug.

Allocations that are created in a generation and still alive afterwards, repeating each time, are what a visit leaves behind.

Common traps

  • Profiling in the simulator. The Mac’s memory behaviour hides jetsam pressure and different allocators.
  • Reading total memory instead of the growth between generations. A high steady number is different from a number that climbs.

They might follow up with

  • What is “created and persistent”? Allocations made during the recording that are still alive at the end.
  • Where do decoded images show up? In VM Tracker’s image regions and as large allocations, far bigger than the file size.

Related questions

  • 3.7.2 How do you find a retain cycle with the Memory Graph debugger?
  • 3.7.5 What is memory footprint, and what gets an iOS app killed?
  • 3.7.1 What is the difference between a leak, abandoned memory, fragmentation and a memory spike?

← How do you find a retain cycle with the Memory Graph debugger?   How do you write a unit test that catches a leak? →