繁体   English   中英

iOS应用程序内存不足而没有收到内存不足警告

[英]iOS app runs out of memory without receiving a low memory warning

我有一个现有的应用程序,我做了一些最近的更改,我一直在测试这些更改。 该应用程序在我测试的每个iPad上运行得非常好(iOS 4和iOS 5)。 在我的应用程序中加载了几个(50+)图像密集的视图后,我得到一个低内存警告,我的viewDidUnload方法被调用,他们正确地将所有控件都清零,我的内存中图像缓存清除了自己,应用程序继续精细。

但是,在iPhone 4和iPhone4s(iOS 5.0.1和iOS 5.1)上,我遇到了一个问题,即我的应用程序内存不足而没有收到低内存警告。 在加载了几个不同的视图后,最终会出现一个新的视图并且大部分是空白的,并且在控制台上我看到内存分配消息,整个手机变得没有响应,有时会杀死我的应用程序。

发生这种情况的特定视图每次都是不同的,因此它与任何一个视图无关,只是随着时间的推移而积累的内存。 我也确认我也没有任何内存泄漏。

这个现有问题是类似的:

IOS应用程序因低内存而被杀死,但未收到内存警告

并且这个答案表明,如果我陷入循环,这可能会发生,但我很确定我的代码不会卡在任何循环中。 我只是在UINavigationController中从一个视图点击到另一个视图,并在每个视图中加载了几个图像。 另外,另一个问题是专门在iPad上发生的,我没有在iPad上看到这个问题,只有iPhone。

顺便说一句,我已经尝试通过NotificationCenter注册低内存通知,并在我的app委托中有一个applicationDidReceiveMemoryWarning方法,并且两者都有断点,并且都没有被调用。 此外,调试器控制台中也没有显示低内存消息。

关于可能发生的事情的任何想法?


在2012年3月26日添加:

有趣的是,当我在新iPad上测试我的应用程序时,它有同样的问题,我在iPhone 4和4s上看到没有收到低内存通知。 所以我想知道我是否看到了与其他线程相同的问题:

新iPad:低内存警告没有出现?

但该线程上的开发人员正在测试仅限iPad的应用程序,因此不会在任何iPhone上测试和发现同样的问题。

我做了一些广泛的测试,并有一个设备列表,我正确地收到了低内存警告和我从未收到它的设备。 到目前为止,我只看到iOS5或更高版本的问题,但是在iOS1和iOS5的iPad1上我没有看到问题,因此它不仅仅是iOS 5上所有设备上的问题。

这是那个清单:

适当的低内存警告

iPad1 4.2.1
iPad1 5.0
iPad1 5.1
iPad2 4.3.3
iPhone3G 4.2.1
iPod 3G 4.3.3
iPhone4 4.3.3

没有低内存警告

iPhone4 5.1
iPhone4s 5.0.1
iPad3 5.1

过去一周,我一直在抨击类似的问题。 我正在做一些不同的事情,但图像有些相关。

您没有说明所有这些图像的位置 - 希望您将它们写入文件系统,然后使用[UIImage imageWithContentsOfFile]将它们加载到视图中(或者如果使用CGImageRefs,则使用CGImageSourceCreateWithURL)。 你想要避免的是将图像存储在内存中(在iOS中没有交换!)。

在我的情况下,我有一些mmap内存来保存图像,我甚至没有映射内存(它将它同步到文件系统),但由于同步需要这么长时间,我被“收费”的那个未同步的内存。 我所做的实际上是在每个文件上调用fcntl(fd,F_FULLSYNC)来强制系统在我继续之前刷新每个块。

我正在iPad 3上开发一款带有大量大图像的应用程序。

如果我将iOS 5.0设置为部署目标,那么如果应用程序消耗太多内存并且应用程序崩溃,则不会调用applicationDidReceiveMemoryWarning

但是, 如果我将iOS 5.1设置为部署目标,则会调用applicationDidReceiveMemoryWarning 因此,操作系统刷新包含先前加载的图像的缓存,并且应用程序不会崩溃。

主要的问题是我使用UIImage imageNamed:加载我的图像,如果你的图像很大,请使用UIImage imageWithContentsOfFile这样它们就不会被缓存(如果@ 2x的大小非常大,这就是一个问题)。

请注意,如果我非常快速地显示许多图像,则在iOS 5.1中不会及时调用applicationDidReceiveMemoryWarning ,而且我崩溃了!

我已经在运行iOS 5.1的iPad 3上找到了确切的行为。 不会调用applicationDidReceiveMemoryWarning,也不会调用UIApplicationDidReceiveMemoryWarningNotification的NSNotifications。 我还在其他一些设备上测试了完全相同的代码,因此您可以将这些代码添加到您的列表中:

适当的低内存警告

iPad 2 5.0.1
iPad 2 4.3.5
iPhone 3GS 5.0.1

没有低内存警告

iPad 3 5.1

模式可以是:具有512 MB的iOS设备或运行5.0.1 - 5.1的1 GB内存。

我没有在这个应用程序中进行任何繁重的UIImage处理。 似乎操作系统的行为已经发生了变化 - 要么是故意杀死应用程序更积极(例如,试图更聪明地杀死看起来好像他们的内存使用过于繁重的应用程序),要么只是打破了低内存通知。

您可以尝试使用仪器运行“Time Profiler”工具吗? 它会告诉你你是否在一个不同的线程中绑定CPU(虽然除非你自己创建它们,但如果是这样的话,我会感到惊讶)。 如果不显示吸烟枪,也可以运行“Allocations”仪器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM