What should an app do on a memory warning, and how reliable is the warning?

6.6.1 · L3 · Interview

Predict first

Does this compile?

import Foundation

let source = DispatchSource.makeMemoryPressureSource(eventMask: [.warning, .critical], queue: .main)
source.setEventHandler { print("pressure") }
source.resume()
  • Yes
  • No

Predict first

Can a memory warning be relied on to arrive before the app is killed for memory?

// A: yes, always
// B: no, it is advisory and a sudden spike can skip it
  • A
  • B

Mental model. A fire alarm that sometimes rings and sometimes does not. You tidy up when it rings, but you design the building so a fire never needs the alarm.

When free memory gets low the system sends a memory warning: didReceiveMemoryWarning on view controllers, UIApplication.didReceiveMemoryWarningNotification for the app, and (outside UIKit) a memory-pressure dispatch source (DispatchSource.makeMemoryPressureSource) with warning and critical events. The right response is to release what you can rebuild: image and data caches, decoded assets for screens that are not visible, preloaded views, and anything you can fetch or recompute. NSCache evicts by itself; hand-written caches must be cleared.

Do not treat the warning as a promise. It is advisory and may not arrive: a sudden spike (decoding a huge image, parsing a big payload) can push the process over its limit with no warning, and a backgrounded app can be killed outright. So the warning is a courtesy to reduce pressure, not a safe point. Keep your peak memory low by design (stream, downsample, work in chunks), and make caches self-limiting. Test with the Xcode “Simulate Memory Warning” command and by profiling the peak, not only the steady state.

A memory-pressure source is a dispatch source with .warning and .critical events, and works outside UIKit.

The warning is a courtesy. The kernel can terminate a process that exceeds its limit without notifying it first.

Common traps

  • Doing expensive work in didReceiveMemoryWarning. You are already under pressure, so only free memory there.
  • Relying on the warning to avoid being killed. A large, sudden allocation skips it.

They might follow up with

  • What is the pressure level “critical” for? It signals the system is about to start killing; release as much as you can.
  • How do you observe memory use? The Xcode memory gauge, os_proc_available_memory(), and Instruments, as covered in the memory section.

Related questions

  • 6.6.2 What is jetsam, and how does it differ from a crash?
  • 3.7.5 What is memory footprint, and what gets an iOS app killed?
  • 2.7.1 What is NSCache, and how is it different from a Dictionary?

What is jetsam, and how does it differ from a crash? →