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为在每个内存级别执行以下操作:
- 警告(非正常) – 重新启动,或延迟自动重新启动不必要的后台应用程序,例如邮件。
- 紧急 – 退出所有后台应用程序,例如Safari和iPod。
- 关键和超越 – 内核将接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的应用程序可能会通过释放当前不在屏幕上的任何图像进行响应。
如何观察内存级别警告?
当系统向您的应用程序发送低内存警告时,立即回应。 当可用内存量低于安全阈值时,iOS会通知所有正在运行的应用程序。 (它不通知暂停的应用程序。)如果您的应用程序收到此警告,它必须释放尽可能多的内存。 这样做的最好方法是删除对高速caching,图像对象和其他稍后可以重新创build的数据对象的强引用。
UIKit提供了几种接收低内存警告的方法,包括:
- 实现应用程序委托的applicationDidReceiveMemoryWarning:方法。
- 覆盖自定义UIViewController子类中的didReceiveMemoryWarning方法。
- 注册以接收UIApplicationDidReceiveMemoryWarningNotificationnotification。
如何减less你的应用程序的内存占用?
- 消除内存泄漏。
- 使资源文件尽可能小。
- 使用核心数据或SQLite的大型数据集。
- 懒惰地加载资源。
- 使用Thumb选项构build您的程序。
如何明智地分配内存?
- 减less对自动释放对象的使用 :使用自动引用计数(ARC),最好是分配/初始化对象,让编译器在适当的时候为你释放它们。 即使对于过去可能已经自动释放的临时对象来说也是如此,以防止它们超出当前方法的范围。
- 对资源施加大小限制 :避免在较小的资源文件加载时加载较大的资源文件。 不要使用高分辨率的图像,而要使用适合iOS设备的尺寸。 如果您必须使用大型资源文件,请在任何给定时间find只加载所需文件的部分的方法。 例如,不是将整个文件加载到内存中,而是使用mmap和munmap函数来映射文件的部分内存。 有关将文件映射到内存的更多信息。
- 避免无限的问题集 :无限的问题集可能需要任意大量的数据来计算。 如果该设置需要比可用内存更多的内存,则您的应用程序可能无法完成计算。 您的应用程序应该尽可能避免这些集合,并处理已知内存限制的问题。