iPhone操作系统内存警告。 不同级别的含义是什么?

关于在iPhone OS设备上pipe理内存的黑色艺术:不同级别的内存警告意味着什么。 1级? 2级? 表盘是否转到11?

背景:经过大量的记忆力testing阶段 – 包括运行我的iPad应用程序与iPod音乐播放器应用程序播放,我倾向于忽略随机而不经常的记忆警告我收到。 我的应用程序从不崩溃。 永远。 我的应用程序是无泄漏的。 而且,好吧,这些警告似乎并不重要。

谢谢,
道格

基本上,这些警告意味着设备内存不足,“如果你可以请释放一些内存,你不会积极使用那将会膨胀! ”。 如果你的内存pipe理很紧张,而且你没有任何实际上可以被丢弃的对象,只要传递消息并忽略它。

内存级警告由SpringBoardlogging。 作为一名应用程序开发人员,您不需要关心它。 只是响应-{application}didReceiveMemoryWarning就足够了。


有4级警告(0到3)。 这些是从内核内存观察器设置的,可以通过非公用函数OSMemoryNotificationCurrentLevel()

 typedef enum { OSMemoryNotificationLevelAny = -1, OSMemoryNotificationLevelNormal = 0, OSMemoryNotificationLevelWarning = 1, OSMemoryNotificationLevelUrgent = 2, OSMemoryNotificationLevelCritical = 3 } OSMemoryNotificationLevel; 

没有logging如何触发水平。 SpringBoardconfiguration为在每个内存级别执行以下操作:

  1. 警告(非正常) – 重新启动,或延迟自动重新启动不必要的后台应用程序,例如邮件。
  2. 紧急 – 退出所有后台应用程序,例如Safari和iPod。
  3. 关键和超越 – 内核将接pipe,可能杀死SpringBoard甚至重新启动。

杀死活动应用程序(jetsam)不是由SpringBoard处理,而是launchd

从OSMemoryNotification.h中 ,

 /* ** Threshold values for notifications */ typedef enum { OSMemoryNotificationLevelAny = -1, OSMemoryNotificationLevelNormal = 0, OSMemoryNotificationLevelWarning = 1, OSMemoryNotificationLevelUrgent = 2, OSMemoryNotificationLevelCritical = 3 } OSMemoryNotificationLevel; 

5个级别的内存警告(-1,3)。

关于内存级警告描述,@ KennyTM的答案非常好。

我想添加几个可能帮助PM和其他人的相关点。


有内存级别警告时应该怎么做?

一旦收到这些警告,你的处理程序方法应立即释放任何不需要的内存。 例如,UIViewController类的默认行为是清除其视图,如果该视图当前不可见; 子类可以通过清除额外的数据结构来补充缺省行为。 维护图像caching的应用程序可能会通过释放当前不在屏幕上的任何图像进行响应。


如何观察内存级别警告?

http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/PerformanceTuning/PerformanceTuning.html

当系统向您的应用程序发送低内存警告时,立即回应。 当可用内存量低于安全阈值时,iOS会通知所有正在运行的应用程序。 (它不通知暂停的应用程序。)如果您的应用程序收到此警告,它必须释放尽可能多的内存。 这样做的最好方法是删除对高速caching,图像对象和其他稍后可以重新创build的数据对象的强引用。

UIKit提供了几种接收低内存警告的方法,包括:

  • 实现应用程序委托的applicationDidReceiveMemoryWarning:方法。
  • 覆盖自定义UIViewController子类中的didReceiveMemoryWarning方法。
  • 注册以接收UIApplicationDidReceiveMemoryWarningNotificationnotification。

如何减less你的应用程序的内存占用?

  • 消除内存泄漏。
  • 使资源文件尽可能小。
  • 使用核心数据或SQLite的大型数据集。
  • 懒惰地加载资源。
  • 使用Thumb选项构build您的程序。

详情请见http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/PerformanceTuning/PerformanceTuning.html


如何明智地分配内存?

  • 减less对自动释放对象的使用 :使用自动引用计数(ARC),最好是分配/初始化对象,让编译器在适当的时候为你释放它们。 即使对于过去可能已经自动释放的临时对象来说也是如此,以防止它们超出当前方法的范围。
  • 对资源施加大小限制 :避免在较小的资源文件加载时加载较大的资源文件。 不要使用高分辨率的图像,而要使用适合iOS设备的尺寸。 如果您必须使用大型资源文件,请在任何给定时间find只加载所需文件的部分的方法。 例如,不是将整个文件加载到内存中,而是使用mmap和munmap函数来映射文件的部分内存。 有关将文件映射到内存的更多信息。
  • 避免无限的问题集 :无限的问题集可能需要任意大量的数据来计算。 如果该设置需要比可用内存更多的内存,则您的应用程序可能无法完成计算。 您的应用程序应该尽可能避免这些集合,并处理已知内存限制的问题。