iPhone操作系统的内存警告。不同级别代表什么意思?

87

关于管理iPhone操作系统设备内存的黑科技:不同级别的内存警告意味着什么。一级?二级?表盘上会到达11吗?

背景:经过长时间的内存压力测试期后,包括在我的iPad应用程序运行iPod音乐播放器应用程序时,我倾向于忽略偶尔收到的随机内存警告。我的应用程序从未崩溃。它没有泄漏。而且,好吧,内存警告似乎并不重要。

谢谢,
道格

3个回答

195

SpringBoard会记录内存警告。作为应用程序开发人员,您不需要过多关注它。只需响应 -{application}didReceiveMemoryWarning 即可。


内存警告分为4个级别(0到3级)。这些警告是从内核内存监视器设置的,并可以通过非公开函数OSMemoryNotificationCurrentLevel()获得。

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

这些级别是如何触发的并没有记录。SpringBoard 在每个内存级别中做以下配置:

  1. 警告(非正常)- 重新启动或延迟自动重新启动非必要的后台应用程序,例如 Mail。
  2. 紧急 - 退出所有后台应用程序,例如 Safari 和 iPod。
  3. 临界及以上 - 内核将接管,可能会杀死 SpringBoard 或甚至重新启动。

结束活动应用程序(jetsam)不由 SpringBoard 处理,而是由 launchd 处理。


谢谢你。在这个问题上,我犹豫了一下是选择你还是喜剧演员威廉姆。幽默获胜。干杯。 - dugla
你好, 我遇到了同样的问题。在连续运行应用程序超过5次后,我会收到“内存警告”消息,级别为1,这个消息出现了20次,但是应用程序并没有崩溃。 但是当我收到“内存警告”消息,级别为2时,我的应用程序就会崩溃。级别2出现在级别1出现近20次之后。我该如何使我的应用程序不崩溃呢? 谢谢 - srikanth rongali
1
@Kenny:更少的内存意味着我们最多可以使用多少内存?我们最多可以有多少活动字节。在我的崩溃日志中,我得到了以下信息。可用页面:371 已连接页面:12192 可清除页面:0 最大进程:DTMobileIS 这是什么意思?我应该注意什么?谢谢。 - srikanth rongali
9
您最好提出一个新问题 - kennytm
@kennytm:在iOS8上还能用吗?我看到这个函数是在libsystem_c.dylib中定义的。如果我可以继续使用它,那就太好了。谢谢。 - focs

102

基本上,这些警告意味着 设备 内存不足,并且,"如果您可以请释放一些您没有在使用的内存,那就太好了!"。如果您的内存管理很紧,且您没有可以实际丢弃的对象,只需将消息传递并忽略它。


26
"如果你能够释放一些你目前未在使用的内存,那就太好了!" 无价之宝;-) 祝好 - dugla
15
你听起来像一位经验丰富的 iPhone 操作系统"打地鼠"内存舞者。 - dugla

12

来源于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类的默认行为是在其视图未当前可见时清除其视图;子类可以通过清除其他数据结构来补充默认行为。保留图像缓存的应用程序可能会释放任何当前不在屏幕上的图像。


如何观察内存级别警告?

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

当系统向您的应用程序发送低内存警告时,请立即响应。iOS在可用内存量降至安全阈值以下时通知所有正在运行的应用程序。 (它不会通知已挂起的应用程序。)如果您的应用程序收到此警告,它必须尽可能释放内存。最好的方法是删除对缓存、图像对象和其他可重新创建的数据对象的强引用。

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

  • 实现您的应用程序委托的applicationDidReceiveMemoryWarning:方法。
  • 在您的自定义UIViewController子类中覆盖didReceiveMemoryWarning方法。
  • 注册UIApplicationDidReceiveMemoryWarningNotification通知。

如何减少您的应用程序的内存占用?

  • 消除内存泄漏。
  • 尽量使资源文件尽可能小。
  • 使用Core Data或SQLite处理大型数据集。
  • 懒加载资源。
  • 使用Thumb选项构建程序。

详细信息请参见http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/PerformanceTuning/PerformanceTuning.html


如何明智地分配内存?

  • 减少使用自动释放对象:使用自动引用计数(ARC),最好是分配/初始化对象,并让编译器在适当的时间释放它们。即使对于临时对象,在过去,您可能已经使用自动释放来防止它们超出当前方法范围,现在也应该如此。
  • 在资源上强制施加大小限制:在可以使用较小文件的情况下避免加载大型资源文件。例如,使用适合基于iOS的设备的大小的图像,而不是使用高分辨率图像。如果必须使用大型资源文件,请找到只在任何给定时间需要的文件部分。例如,而非将整个文件加载到内存中,请使用mmap和munmap函数将文件的部分映射到内存中和移出内存。有关将文件映射到内存中的更多信息,请参见相关文档。
  • <

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接