简体   繁体   English

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

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

I have an existing app that I made some recent changes to and I have been testing those changes. 我有一个现有的应用程序,我做了一些最近的更改,我一直在测试这些更改。 The app works perfectly fine on every iPad I test it on (iOS 4 and iOS 5). 该应用程序在我测试的每个iPad上运行得非常好(iOS 4和iOS 5)。 After loading several (50+) image-heavy views in my app I get a low memory warning and my viewDidUnload methods get called and they properly nil out all of their controls and my in-memory image cache clears itself out and the app continues just fine. 在我的应用程序中加载了几个(50+)图像密集的视图后,我得到一个低内存警告,我的viewDidUnload方法被调用,他们正确地将所有控件都清零,我的内存中图像缓存清除了自己,应用程序继续精细。

However, on an iPhone 4 and iPhone4s (iOS 5.0.1 and iOS 5.1) I run into a problem where my application runs out of memory without ever receiving a low memory warning. 但是,在iPhone 4和iPhone4s(iOS 5.0.1和iOS 5.1)上,我遇到了一个问题,即我的应用程序内存不足而没有收到低内存警告。 After loading several different views, eventually a new view will come up and be mostly blank and on the console I see memory allocation messages and the whole phone becomes un-responsive and sometimes kills my app. 在加载了几个不同的视图后,最终会出现一个新的视图并且大部分是空白的,并且在控制台上我看到内存分配消息,整个手机变得没有响应,有时会杀死我的应用程序。

The particular view that this happens on is different every time, so it's not related to any one view, just the accumulation of memory over time. 发生这种情况的特定视图每次都是不同的,因此它与任何一个视图无关,只是随着时间的推移而积累的内存。 I have also confirmed that I don't have any memory leaks either. 我也确认我也没有任何内存泄漏。

This existing question is similar: 这个现有问题是类似的:

IOS app killed for Low Memory but no Memory Warning received IOS应用程序因低内存而被杀死,但未收到内存警告

and that answer suggests that this could happen if I'm stuck in a loop, but I'm pretty sure that my code isn't stuck in any loops. 并且这个答案表明,如果我陷入循环,这可能会发生,但我很确定我的代码不会卡在任何循环中。 I'm just clicking through from one view to another in a UINavigationController and several images load in each view. 我只是在UINavigationController中从一个视图点击到另一个视图,并在每个视图中加载了几个图像。 Also, the other question was specifically happening on an iPad where I'm not seeing this issue on an iPad, only iPhones. 另外,另一个问题是专门在iPad上发生的,我没有在iPad上看到这个问题,只有iPhone。

BTW, I've tried registering for the low memory notification through NotificationCenter and have an applicationDidReceiveMemoryWarning method in my app delegate and have breakpoints at both and neither get called. 顺便说一句,我已经尝试通过NotificationCenter注册低内存通知,并在我的app委托中有一个applicationDidReceiveMemoryWarning方法,并且两者都有断点,并且都没有被调用。 Also, no low memory message shows up in the debugger console either. 此外,调试器控制台中也没有显示低内存消息。

Any ideas on what might be happening? 关于可能发生的事情的任何想法?


Added on 3/26/2012: 在2012年3月26日添加:

Interestingly enough, when I tested my app on the new iPad, it has this same problem that I'm seeing on the iPhone 4 and 4s where the low memory notification is not being received. 有趣的是,当我在新iPad上测试我的应用程序时,它有同样的问题,我在iPhone 4和4s上看到没有收到低内存通知。 So I'm wondering if I'm seeing the same problem as this other thread: 所以我想知道我是否看到了与其他线程相同的问题:

The New iPad: Low Memory Warnings Not Appearing? 新iPad:低内存警告没有出现?

but that the developer on that thread is testing an iPad-only app and therefore not testing and finding this same problem on any iPhones. 但该线程上的开发人员正在测试仅限iPad的应用程序,因此不会在任何iPhone上测试和发现同样的问题。

I have done some extensive testing and have a list of devices where I properly received the low memory warning and devices where I don't ever receive it. 我做了一些广泛的测试,并有一个设备列表,我正确地收到了低内存警告和我从未收到它的设备。 So far I only see the problem on iOS5 or greater, however on iPad1s with iOS 5.0 and 5.1 I don't see the issue, so it's not just a problem on all devices on iOS 5. 到目前为止,我只看到iOS5或更高版本的问题,但是在iOS1和iOS5的iPad1上我没有看到问题,因此它不仅仅是iOS 5上所有设备上的问题。

Here is that list: 这是那个清单:

Proper Low Memory Warning 适当的低内存警告

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

No Low Memory Warning 没有低内存警告

iPhone4 5.1
iPhone4s 5.0.1
iPad3 5.1

I've been banging my head on similar problems for the past week. 过去一周,我一直在抨击类似的问题。 I'm doing something different but with images so somewhat related. 我正在做一些不同的事情,但图像有些相关。

You don't say where all those images are located - hopefully you write them to the file system, then load them into views using [UIImage imageWithContentsOfFile] (or if using CGImageRefs, then use a CGImageSourceCreateWithURL). 您没有说明所有这些图像的位置 - 希望您将它们写入文件系统,然后使用[UIImage imageWithContentsOfFile]将它们加载到视图中(或者如果使用CGImageRefs,则使用CGImageSourceCreateWithURL)。 What you want to avoid is having the images in memory (no swapping in iOS!). 你想要避免的是将图像存储在内存中(在iOS中没有交换!)。

in my case I had some mmap memory to hold the images, I had even unmapped the memory (which syncs it to the file system), but since syncing takes so long, I was being "charged" for that unsynced memory. 在我的情况下,我有一些mmap内存来保存图像,我甚至没有映射内存(它将它同步到文件系统),但由于同步需要这么长时间,我被“收费”的那个未同步的内存。 What I did was essentially call fcntl(fd, F_FULLSYNC) on each of these files to force the system to flush each block before I continued. 我所做的实际上是在每个文件上调用fcntl(fd,F_FULLSYNC)来强制系统在我继续之前刷新每个块。

I'm working on an app with tons of big images, on an iPad 3. 我正在iPad 3上开发一款带有大量大图像的应用程序。

If I set iOS 5.0 as the Deployment Target, applicationDidReceiveMemoryWarning does not get called if the app consumes too much memory, and the app crashes. 如果我将iOS 5.0设置为部署目标,那么如果应用程序消耗太多内存并且应用程序崩溃,则不会调用applicationDidReceiveMemoryWarning

However, applicationDidReceiveMemoryWarning does get called if I set iOS 5.1 as the Deployment Target . 但是, 如果我将iOS 5.1设置为部署目标,则会调用applicationDidReceiveMemoryWarning The OS thus flushes the cache containing the images that were previously loaded and the app doesn't crash. 因此,操作系统刷新包含先前加载的图像的缓存,并且应用程序不会崩溃。

The main problem is that I use UIImage imageNamed: to load my images, if your images are big use UIImage imageWithContentsOfFile instead so that they don't get cached (which is an issue if the size of the @2x is very big). 主要的问题是我使用UIImage imageNamed:加载我的图像,如果你的图像很大,请使用UIImage imageWithContentsOfFile这样它们就不会被缓存(如果@ 2x的大小非常大,这就是一个问题)。

Note that if I display many images very quickly, applicationDidReceiveMemoryWarning doesn't get called in time in iOS 5.1, and I crash! 请注意,如果我非常快速地显示许多图像,则在iOS 5.1中不会及时调用applicationDidReceiveMemoryWarning ,而且我崩溃了!

I have found exactly the behaviour on an iPad 3 running iOS 5.1. 我已经在运行iOS 5.1的iPad 3上找到了确切的行为。 applicationDidReceiveMemoryWarning does not get called, nor NSNotifications for UIApplicationDidReceiveMemoryWarningNotification. 不会调用applicationDidReceiveMemoryWarning,也不会调用UIApplicationDidReceiveMemoryWarningNotification的NSNotifications。 I also tested the exact same code on some other devices, so you can add these to your list: 我还在其他一些设备上测试了完全相同的代码,因此您可以将这些代码添加到您的列表中:

Proper low memory warning 适当的低内存警告

iPad 2 5.0.1 iPad 2 5.0.1
iPad 2 4.3.5 iPad 2 4.3.5
iPhone 3GS 5.0.1 iPhone 3GS 5.0.1

No low memory warning 没有低内存警告

iPad 3 5.1 iPad 3 5.1

The pattern could be: iOS devices with 512 MB or 1 GB memory running 5.0.1 - 5.1. 模式可以是:具有512 MB的iOS设备或运行5.0.1 - 5.1的1 GB内存。

I'm not doing any heavy UIImage handling in this app. 我没有在这个应用程序中进行任何繁重的UIImage处理。 It seems that the behaviour from the OS has changed - either it is deliberately killing apps more aggressively (eg trying to be smarter about killing apps that look as though they have too onerous memory usage), or the low memory notifications are just broken. 似乎操作系统的行为已经发生了变化 - 要么是故意杀死应用程序更积极(例如,试图更聪明地杀死看起来好像他们的内存使用过于繁重的应用程序),要么只是打破了低内存通知。

Can you try running in Instruments for the "Time Profiler" tool? 您可以尝试使用仪器运行“Time Profiler”工具吗? It'll tell you if you're CPU bound in a different thread (though unless you create them yourself I'll be surprised if that's the case). 它会告诉你你是否在一个不同的线程中绑定CPU(虽然除非你自己创建它们,但如果是这样的话,我会感到惊讶)。 Also good to run the "Allocations" instrument if that doesn't reveal smoking guns. 如果不显示吸烟枪,也可以运行“Allocations”仪器。

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

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