When I press the home button my app is suspended correctly, however it only lasts a few minutes. If I leave it for a short while and return to it the app starts up fresh.
I'm not running any background tasks in my app and other apps stay suspended for much, much longer than mine.
What could be the potential causes of this? Is it likely I have operations running in the background that I'm not aware of and iOS is killing my app when it is short on memory?
The apps that are using the most memory are terminated first in the background. So the likely cause is that your app is consuming more memory than you think it is. I'd start with ensuring that your memory is being managed correctly.
Apple - App States and Multitasking
Related
I'm building my app on a development device that does not have too many apps running at the same time. I'm expecting my customers to run the app with any number of other apps open. To ensure my app wont crash due to memory issues, I would like to test my app under expected operating conditions.
This poses a question - does the number of other apps visible in the double tap home button bar affects the memory usage of the device? In other words, if I open every app on the device, then start my app, am I more likely to receive memory warnings than if I have all other apps closed?
I remember hearing a WWDC presentation that mentioned that for some apps that use <8mb of memory, their memory gets written to disk while the app is minimized, not sure what this changes.
Thank you for the clarification.
does the number of other apps visible in the double tap home button
bar affects the memory usage of the device?
No. The multi-tasking bar is just a history of recent apps. Some of them may still be in memory, others not. There is no way for you to know just by looking at it.
When low on memory, iOS will terminate the most memory-hungry background apps first. If your app allocates a lot of memory in a short period of time, it can happen that iOS isn't able to reclaim memory fast enough and will terminate your app immediately.
All you can do is reduce your footprint as much as possible, and try not to allocate huge buffers in one go.
Just a quick note. I found out that having other apps open does affect real memory allocation. Profiling the app with "activity monitor" lets you see which apps are currently loaded in memory and how much they use. Assuming the device has 512mb, you have 512 - (what's open) to use, and iOS may kill some apps to free up memory for your app.
Yes I think the number of opened apps affects the way your app
receives memory warning. Closing all the apps running in the
background or restarting the device can decrease the memory warning
messages sent to your app (you can see this effect by using instruments).
Advise:
When you receive memory warning try to do the following:
- Stop timers and other periodic tasks.
- Stop any running metadata queries.
- Do not initiate any new tasks.
- Pause movie playback (except when playing back over AirPlay).
- Enter into a pause state if your app is a game.
- Throttle back OpenGL ES frame rates.
- Suspend any dispatch queues or operation queues executing non-critical code. (You can continue processing network requests and other time-sensitive background tasks while inactive.)
I have a map based and location based app which I put into the background. I then start a a game app (agent dash) after the game app has finished initializing I noticed that my app has been killed: 9 in the device log. Sometimes I get a memory warning message, sometimes not. But is it possible for one app to cause another to be terminated. If I run the my app on its own there is no problem. I run other apps in the foreground and no problem. Also if an app can cause mine to be terminated can I generate a restart? Thanks
Agent dash must be an memory intensive app, so when the iOS feels its running out of memory it generates memory warnings which each app needs to handle. It can even kill your app if it needs more memory. The primary thing iOS takes into consideration is that it wants to keep the app which the user is using alive. And no you can't restart your app pro grammatically the user will have to do it if he wants to.
While the device is powered on, is it possible for iOS to automatically terminate my app (calling applicationWillTerminate:) while it's in the background?
I'm also curious what happens in two other cases, three in total:
Device is powered on
Device is powered off
Device loses battery
I'm asking because I want to know how often applicationWillTerminate: is likely to get called. I want to know this because that's where I'm registering for remote notifications. And if there's a failure sending the device token to the server, I want to know how likely it is that that method will get called again (i.e., retry sending the device token to the server).
If your application supports multitasking (the default for anything linked against iOS 4.0+), this method will almost never be called. The documentation says it may be called in cases where the application is running in the background and the system wants to terminate. However, in my experience, I've only ever seen this actually called when running a music app that's actively playing music in the background and the system is jettisoning everything. In cases where I have background tasks running (not music, but short-term background tasks), I've seen the app terminated without this method being called.
I wouldn't ever rely on this being called and try and do all the clean-up you need to do in your delegate methods for transitioning into the background and your background task completion blocks (which do get executed for at least a few seconds before the app gets jettisoned).
Not only can iOS terminate your app automatically, but the user can kill it manually. In fact, the only time the user can kill your app is when it's in the background. Furthermore, when your app is "in the background" it's more likely to be suspended than actually running, so don't count on doing a lot of processing when you're not the foreground app.
As for how likely it is that you'll get -applicationWillTerminate:, that'll depend on the user and how they're using their device. You should handle it appropriately when you get it, and go about your business otherwise.
When memory is running low, iOS can shut down your app, calling applicationWillTerminate.
The docs say this about the method:
... However, this method may be called in situations where the application is running in the background (not suspended) and the system needs to terminate it for some reason.
Check out iOS Developer Library : iOS App Programming Guide : App Termination.
I've got a location service running in the background, but I'm finding that sometimes if the user runs a number of other apps in the foreground my app will get unloaded.
Using Instruments my app currently consumes about 1.2MB in the background. A project with an empty view consumes about 600KB in the background. I know I have some improvements that can be made to bring this closer to the minimum, but beyond that is there anything else I can do to prevent my app from getting unloaded? Since my app is actually doing something "useful" in the background, is there a way to indicate this to the system so that my app will get preference some other suspended app like a game which doesn't need that memory?
Does anyone know how the algorithm works in terms of which background apps are flushed first? Is it by order of memory usage, by oldest open app in the foreground, by oldest run thread in the background?
To expand on the question:
What are the right trade-offs to be made in this service scenario? I can move my CLLocation into the AppDelegate. Should I force my ViewController to unload every time it enters into the background, such that my background memory usage is the absolute minimum, but trading off start-up time and forcing a reload of cached map tiles? Or can I wait until I get the didReceiveMemoryWarning before releasing the viewController?
If I had some sense of the order in which apps will be killed that would help to make the right trade-offs. For instance is there a round robin approach where the oldest suspended app gets the warning first. Then on coming around again if the system still needs more memory it does the actually killing? Or does the system issue the memory warning to an app, sees that not enough has been freed and than kills the app, then moves onto the next suspended app. Or is the order by memory usage?
Any best practices in on this subject would be appreciated.
Update:
After spending half a day converting my app from ARC & Storyboard back to to manual allocation, I still found that the background memory usage was roughly the same. Even though I removed all view controllers from the view and released them, the system still doesn't free that memory immediately. So in the end my app was just as likely to be killed as it was when I was using ARC. What's more interesting is that my app never gets a didRecieveMemoryWarning and my viewDidUnload never gets called, my app just gets killed without notification.
Luckily it was pointed out to me in the Apple Developer forum that if MonitoringSignificantLocationChanges is enabled even if my app is killed it will get reloaded on a significant location change.
I just had to be cognizant that my app could be re-launched from the background and had to use [[UIApplication sharedApplication] applicationState] to handle that event accordingly.
Well you can't stop iOS from killing your app, that's just the way the system works.
If there is a memory low memory warning iOS will kill the some of the apps that are running in the background.
Tips are just keep your memory usage as low as posible.
I have an iPhone application I'm testing - I've just noted when testing it on a device that sometimes when I resume it (i.e. launch it again in the "multitasking" sense when I expect it to appear and continue on) the startup image appears. As if it totally restarted.
Would this be an indication of memory issue with the app?
Good question. I've noticed this as well and wondered also. It might not be this app that has an issue though, but other apps have required extra memory which caused the system to take memory from this app. Im not sure exactly because (if I recall correctly) the resumed app restarts on the screens it was on, so it didnt lose state. I wonder if in this case, iOS has unloaded some of the backgrounded task's code and its taking a bit of time to read the code back in, so it puts that screen up. However, if this was the case, then the app would really need to be idle and not active in the background.