Improve your app’s performance by analyzing memory-use metrics and making changes to maximize memory efficiency.
The memory (RAM) on a device is a limited resource that’s shared by apps, operating system processes, and the kernel. iOS has techniques for satisfying the various demands on memory, but these techniques come at the expense of speed and responsiveness. For example, iOS might transfer a memory-intensive app to solid-state storage when the app is running in the background. The app then incurs a delay when coming back to the foreground or attempting to run a background task.
If the app is using too much memory, iOS sends it a warning. You get notifications of such warnings in the form of a crash report. This report, with an
EXC exception type and
MEMORY subtype, indicates that the app has approached its memory limit. It doesn’t mean that iOS has terminated the app, only that it has detected a memory-use problem. The memory limit that triggers the exception depends on the device, and once an app exceeds this limit, iOS terminates it. If the app is terminated when it’s in the foreground, the user sees it disappear. The next time the user opens the app, it launches from the beginning, which takes longer than resuming from the background.
Because the device shares memory between apps and iOS processes, one app using too much memory can compromise the user experience across the whole device. Limiting the amount of memory an app uses can benefit users even when they’re using other apps.
Understand Memory-Use Metrics
Xcode’s Metrics organizer and MetricKit each provide two metrics about memory use in an app. The first metric is peak memory use, which is the highest memory use observed in any of the samples taken. iOS collects this metric by sampling the app’s memory use periodically throughout the day. The second metric is memory use observed on suspension, measured when the app enters the background.
iOS measures memory use as the number of memory pages in use multiplied by page size, which is typically 16 KB. Writing a single byte to allocated memory can increase memory use by 16 KB if iOS must allocate a new page to store that byte.
Data structures defined in the app’s executable or linked libraries and frameworks contribute to the memory-use metric. Memory that the app allocates at runtime doesn’t initially contribute to this metric. Such memory is “clean,” and iOS doesn’t need to dedicate physical RAM to store it. When the app writes to the allocated memory, it becomes “dirty,” and iOS dedicates RAM to storing its content, as shown in the illustration below. Dirty memory contributes to the memory-use metric.
The organizer shows memory use broken down by version of your app, on each of the device models on which users run the app.