Out of Memory (OOM) Terminations

What is an OOM?

Crashlytics reports crashes caused by signals, Mach exceptions and uncaught C++/Obj-C exceptions. However, these are not the only reasons your app may unexpectedly exit. As you use RAM on an end user’s device, the operating system can decide to reclaim that memory for other processes and terminate your app–we call this an Out of Memory (OOM) termination. Unfortunately, we cannot make use of the same mechanisms to capture OOMs as we do for crashes.

How do we detect OOMs?

Every time we see an app launch, we systematically eliminate possible reasons for a previous termination. Only when we rule out some directly observable reasons–a crash, the user force-quitting the app, or the OS or app updating–do we conclude an OOM has occurred. We only report the OOM if the app was in the foreground before the second launch. This system is partially modelled after the one described by Ali Ansari and Grzegorz Pstrucha in this blog post: https://code.facebook.com/posts/1146930688654547/reducing-fooms-in-the-facebook-ios-app/.

../_images/oom-definitions.png

Note

If you call exit in your app, that termination will affect your OOM-free session counts. Calling exit is explicitly discouraged by Apple (https://developer.apple.com/library/ios/qa/qa1561/_index.html).

How do OOMs and OOM sessions relate to Answers sessions?

Answers sessions are based pairing foreground and background events, whereas OOM sessions are based on launches–they are not directly comparable. See (https://docs.fabric.io/apple/answers/answers-metrics.html#sessions) for more information about Answers sessions.

Because OOMs cause app termination without reporting transitions to the background state, Answers does not record a session for that launch. This typically results in inverse proportions between OOM and Answers session counts.

How should you go about debugging OOMs?

Avoiding OOMs is all about improving the memory performance of your app. Apple focuses heavily on app performance, and provides tools as well as tutorials on how to use them. If you suspect your app is being terminated due to memory pressure, we recommend trying the following:

Some new tools became available starting in Xcode 8:

You can also implement applicationDidReceiveMemoryWarning in your app delegate to be notified when your app places too much pressure on system memory or subscribe to the UIApplicationDidReceiveMemoryWarningNotification notification. Implement didReceiveMemoryWarning in any view controller subclass for more targeted notifications, or if you have an idea of a particular view controller that may cause problems (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/#//apple_ref/occ/intfm/UIApplicationDelegate/applicationDidReceiveMemoryWarning:).