iPhone OS Memory Warnings. What Do The Different Levels Mean?
Solution 1:
Memory level warnings are logged by SpringBoard. As an app developer you don't need to care about it. Just responding to -{application}didReceiveMemoryWarning
is enough.
There are 4 levels of warnings (0 to 3). These are set from the kernel memory watcher, and can be obtained by the not-so-public function OSMemoryNotificationCurrentLevel()
.
typedef enum {
OSMemoryNotificationLevelAny = -1,
OSMemoryNotificationLevelNormal = 0,
OSMemoryNotificationLevelWarning = 1,
OSMemoryNotificationLevelUrgent = 2,
OSMemoryNotificationLevelCritical = 3
} OSMemoryNotificationLevel;
How the levels are triggered is not documented. SpringBoard is configured to do the following in each memory level:
- Warning (not-normal) — Relaunch, or delay auto relaunch of nonessential background apps e.g. Mail.
- Urgent — Quit all background apps, e.g. Safari and iPod.
- Critical and beyond — The kernel will take over, probably killing SpringBoard or even reboot.
Killing the active app (jetsam) is not handled by SpringBoard, but launchd
.
Solution 2:
Basically the warnings mean that the device is running low on memory, and that, "If you could please free some memory you aren't actively using that'd be swell!". If your memory management is tight, and you have no objects that could practically be discarded, just pass the message along and ignore it.
Solution 3:
From OSMemoryNotification.h,
/*
** Threshold values for notifications
*/
typedef enum {
OSMemoryNotificationLevelAny = -1,
OSMemoryNotificationLevelNormal = 0,
OSMemoryNotificationLevelWarning = 1,
OSMemoryNotificationLevelUrgent = 2,
OSMemoryNotificationLevelCritical = 3
} OSMemoryNotificationLevel;
totoal 5 levels of memory warning (-1,3).
Regarding Memory Level warning description, @KennyTM's answer is excellent.
I want to add several related points which may help PM and others.
What should you do when having Memory Level Warning?
Upon receiving any of these warnings, your handler method should respond by immediately freeing up any unneeded memory. For example, the default behavior of the UIViewController class is to purge its view if that view is not currently visible; subclasses can supplement the default behavior by purging additional data structures. An app that maintains a cache of images might respond by releasing any images that are not currently onscreen.
How to observe Memory Level warning?
From http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/PerformanceTuning/PerformanceTuning.html
When the system dispatches a low-memory warning to your app, respond immediately. iOS notifies all running apps whenever the amount of free memory dips below a safe threshold. (It does not notify suspended apps.) If your app receives this warning, it must free up as much memory as possible. The best way to do this is to remove strong references to caches, image objects, and other data objects that can be recreated later.
UIKit provides several ways to receive low-memory warnings, including the following:
- Implement the applicationDidReceiveMemoryWarning: method of your app delegate.
- Override the didReceiveMemoryWarning method in your custom UIViewController subclass.
- Register to receive the UIApplicationDidReceiveMemoryWarningNotificationnotification.
How to Reduce Your App’s Memory Footprint?
- Eliminate memory leaks.
- Make resource files as small as possible.
- Use Core Data or SQLite for large data sets.
- Load resources lazily.
- Build your program using the Thumb option.
Details at http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/PerformanceTuning/PerformanceTuning.html
How to allocate memory wisely?
- Reduce your use of autoreleased objects : With automatic reference counting (ARC), it is better to alloc/init objects and let the compiler release them for you at the appropriate time. This is true even for temporary objects that in the past you might have autoreleased to prevent them from living past the scope of the current method.
- Impose size limits on resources : Avoid loading a large resource file when a smaller one will do. Instead of using a high-resolution image, use one that is appropriately sized for iOS-based devices. If you must use large resource files, find ways to load only the portion of the file that you need at any given time. For example, rather than load the entire file into memory, use the mmap and munmap functions to map portions of the file into and out of memory. For more information about mapping files into memory.
- Avoid unbounded problem sets : Unbounded problem sets might require an arbitrarily large amount of data to compute. If the set requires more memory than is available, your app may be unable to complete the calculations. Your apps should avoid such sets whenever possible and work on problems with known memory limits.