What is the difference between a leak, abandoned memory, fragmentation and a memory spike?

3.7.1 · L3 · Interview

Reported at: Razorpay

Predict first

A screen is dismissed but an app-wide array of “recent screens” still holds it, so it never deinits. What is this?

// A: a leak
// B: abandoned memory
// C: fragmentation
  • A
  • B
  • C

Mental model. A leak is a room whose door you lost. Abandoned memory is a room you can still enter but never use. Fragmentation is a hall full of tiny unusable gaps. A spike is hosting everyone at once.

A leak is memory nothing can reach any more, typically a retain cycle: no pointer from a live root leads to it, and it can never be freed. Abandoned memory is still reachable (a singleton, a cache or an array of old view controllers still points at it) but is no longer needed. It is the most common problem in Swift apps, and Leaks does not flag it because, technically, it is not leaked. Fragmentation is free memory scattered in gaps too small or too spread out to reuse or return to the system, so the footprint stays high although little is in use. A spike is a short-lived peak (decoding a huge image, parsing a large payload at once) that can exceed the limit even though everything is freed afterwards.

Telling them apart decides the fix. Cycles get a weak or unowned link. Abandoned memory needs an owner who lets go (clear the cache, drop the reference on dismiss). Fragmentation needs fewer, larger or more uniform allocations. Spikes need streaming, downsampling or smaller batches.

It is reachable from a live root, so it is not a leak in the Leaks sense. It is abandoned: held but no longer needed.

LeakAbandonedFragmentationSpike
Still reachablenoyesn/ayes, briefly
Typical causeretain cycleunbounded cache, observermany odd-sized allocationswhole payload decoded at once
Best toolMemory Graph, LeaksAllocations generationsVM Tracker, malloc statsAllocations peak, Time Profiler
Fixbreak a linkgive it an owner who lets gofewer, uniform allocationsstream or downsample

Common traps

  • “Instruments says no leaks, so memory is fine.” Abandoned memory and spikes pass the Leaks check.
  • Fixing growth with a weak reference when the real owner is a cache. Decide who should have let go.

They might follow up with

  • Which is most common in a Swift app? Abandoned memory: unbounded caches, observers, and view controllers kept in arrays.
  • Does ARC prevent fragmentation? No. It frees objects, but the allocator can still be left with scattered gaps.

Related questions

  • 3.3.1 What is a retain cycle, and how do you find and fix one?
  • 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?

How do you find a retain cycle with the Memory Graph debugger? →