关于在 iPhone OS 设备上管理内存的魔法:不同级别的内存警告是什么意思。 1级? 2级?表盘是11吗?
背景:经过广泛的内存压力测试 - 包括在播放 iPod 音乐播放器应用程序的情况下运行我的 iPad 应用程序,我倾向于忽略我收到的随机但不常见的内存警告。我的应用程序从不崩溃。曾经。我的应用程序没有泄漏。而且,嗯,mems 警告似乎并不重要。
谢谢,道格
内存级别警告由 SpringBoard 记录。作为应用程序开发人员,您不需要关心它。只需回复 -{application}didReceiveMemoryWarning
就足够了。
有 4 个级别的警告(0 到 3)。这些是从内核内存观察程序设置的,并且可以通过 not-so-public function OSMemoryNotificationCurrentLevel()
获得。
typedef enum {
OSMemoryNotificationLevelAny = -1,
OSMemoryNotificationLevelNormal = 0,
OSMemoryNotificationLevelWarning = 1,
OSMemoryNotificationLevelUrgent = 2,
OSMemoryNotificationLevelCritical = 3
} OSMemoryNotificationLevel;
没有记录级别是如何触发的。 SpringBoard 配置为在每个内存级别执行以下操作:
警告(不正常) - 重新启动或延迟自动重新启动非必要的后台应用程序,例如邮件。紧急 — 退出所有后台应用程序,例如 Safari 和 iPod。关键和超越——内核将接管,可能会杀死 SpringBoard 甚至重新启动。
终止活动应用程序 (jetsam) 不是由 SpringBoard 处理的,而是由 launchd
处理的。
基本上,这些警告意味着设备内存不足,并且“如果你可以请释放一些你没有积极使用的内存,那会膨胀!”。如果您的内存管理很严密,并且您实际上没有可以丢弃的对象,则只需传递消息并忽略它。
/*
** Threshold values for notifications
*/
typedef enum {
OSMemoryNotificationLevelAny = -1,
OSMemoryNotificationLevelNormal = 0,
OSMemoryNotificationLevelWarning = 1,
OSMemoryNotificationLevelUrgent = 2,
OSMemoryNotificationLevelCritical = 3
} OSMemoryNotificationLevel;
共有 5 级内存警告 (-1,3)。
关于内存级别警告描述,@KennyTM 的回答非常好。
我想添加几个可能对 PM 和其他人有所帮助的相关点。
出现内存级别警告时该怎么办?
收到任何这些警告后,您的处理程序方法应立即释放任何不需要的内存来响应。例如,UIViewController 类的默认行为是在视图当前不可见时清除其视图;子类可以通过清除其他数据结构来补充默认行为。维护图像缓存的应用程序可能会通过释放当前不在屏幕上的任何图像来做出响应。
如何观察内存级别警告?
当系统向您的应用发送内存不足警告时,请立即响应。只要可用内存量低于安全阈值,iOS 就会通知所有正在运行的应用程序。 (它不会通知暂停的应用程序。)如果您的应用程序收到此警告,它必须释放尽可能多的内存。最好的方法是删除对缓存、图像对象和其他可以稍后重新创建的数据对象的强引用。
UIKit 提供了几种接收内存不足警告的方法,包括:
实现应用程序委托的 applicationDidReceiveMemoryWarning: 方法。
覆盖自定义 UIViewController 子类中的 didReceiveMemoryWarning 方法。
注册以接收 UIApplicationDidReceiveMemoryWarningNotification 通知。
如何减少应用程序的内存占用?
消除内存泄漏。
使资源文件尽可能小。
对大型数据集使用 Core Data 或 SQLite。
懒加载资源。
使用 Thumb 选项构建您的程序。
如何明智地分配内存?
减少对自动释放对象的使用:使用自动引用计数 (ARC),最好分配/初始化对象并让编译器在适当的时候为您释放它们。即使对于过去您可能已经自动释放以防止它们超出当前方法范围的临时对象也是如此。
对资源施加大小限制:避免在较小的资源文件加载时加载较大的资源文件。不要使用高分辨率图像,而是使用大小适合基于 iOS 的设备的图像。如果您必须使用大型资源文件,请找到在任何给定时间仅加载您需要的文件部分的方法。例如,不是将整个文件加载到内存中,而是使用 mmap 和 munmap 函数将文件的部分映射到内存中和从内存中映射出。有关将文件映射到内存的更多信息。
避免无界问题集:无界问题集可能需要任意大量数据来计算。如果集合需要的内存超出可用内存,您的应用可能无法完成计算。您的应用程序应尽可能避免此类集合,并解决已知内存限制的问题。
不定期副业成功案例分享
libsystem_c.dylib
中定义的。如果我可以继续使用它,那就太好了。谢谢