In IOS5 - If my app gets suspended, can I somehow prevent it from being wiped out from memory if IOS requires the memory?
If it does get wiped out, can I ask IOS to put it again in suspended state after it regains the memory back again?
No, you cannot do that. The memory is under control of the watch dog.
Instead make your app preserves the last state to speed up the next start. Then it seems for the user that the app wasn't ever killed.
Ios will only kill your app if you use TOO MUCH memory ... other wise it will never be killed so try to keep your memory consupmtion very low. Instead of alocating memory try to use mmap insted
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.)
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
I've been surprised that iOS 5.1 does not manage memory quite as I expected. When the device is running a lot of apps, it appears that iOS does not kill memory hogging apps in the background, but sends memory warning to my own app as well.
For example showing a UIImagePicker crashed the app on two test devices. Double tapping the home key and killing some of the background apps prevents the app from receiving the memory warning and crashing.
I'm wandering if iOS would not free up memory for me, is it acceptable to show some sort of alert view notifying the user that the memory is low and some of the background tasks have to be killed?
I'm at a loss of how to deal with such events - does it take time for iOS to clean up some memory (while apps respond to memory warnings)?
iOS does a lot of stuff before bothering you with memory warnings, including killing backgrounded Apps. Since iOS 5, iOS is even going to annoy you as less as possible with memory warnings, meaning that you only get one if there really is a need for you to get rid of stuff that is using memory but not needed right now (and that you can safely recreate in the future without taking hours for it). If your App crashes without giving you a memory warning first, chances are that you allocated so much memory that the system can't tell you that its running out of memory before it decides to kill you, the reason for this is that the memory warning is scheduled on the runloop of the main thread and until you give the runloop time to do another iteration, you won't receive the warning.
Also, Apple doesn't like you to tell the user that there is a memory problem; Its your App that has to deal with it, not the user! So its very very likewise that your App gets rejected if a memory warning comes up while the review team is reviewing your app (rumor says that they send these warnings to test how your App reacts to them)
Soo, to sum it up: iOS does work like you expected by killing what it can and even shutting down other system daemons, only after this happening you will be notified that memory is low. The correct way to respond to these warnings is to free up as much memory as you can, start with the big stuff that can be easily recreated in the future (eg. if your app shows loads of pictures but not all are visible at a time, throw away the ones that aren't visible right now). Telling the user is the wrong way to deal with the problem and Apple doesn't like it, so try to solve the problem on your end.
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'm reading up on the leak-finding tools for iPhone development and intentionally inserting and looking for memory leaks in my small program before I get into a bigger, harder-to-debug project.
It's no problem to identify a memory leak that, say, occurs in a regularly invoked method like responding to a touch event. The leak instrument will eventually identify virtual memory that is unclaimed.
I'm more worried about a leak in code for exiting the entire system. Once I completely exit my app, is it a concern that something wasn't deallocated, or does iphone OS automatically reclaim all user mem at that point?
This issue is unclear to me after reading quite a bit of documentation, and without knowing anything else, I assume it must work like other OS's in that regard and just take back all user space. If that's so, won't I be fine cleaning up regular leaks so my app can run for any amount of time with bounded memory, then not worry so much that everything gets freed up at exit?
Also, if it is critical to free everything before exiting because it will not be reclaimed by the OS, is there a good way to keep my app alive in the instruments after exit for inspection? When I press the home button in the simulator or on the device haven't I already lost the chance to detect exit-time leaks?
Yes, ending your program will release every bit of memory held by it. Anything otherwise is an OS bug, and you're unlikely to find that occurring.
EDIT: I bet your asking this because documentation says "iPhone doesn't support garbage collection." That statement, however, doesn't apply to freeing memory when a program ends. It's only talking about how you have to handle freeing your own memory while your program is running.
The iPhone should be using virtual memory, so (theoretically anyways) the OS will clean everything up when a leaky app exits.