I want to test the behaviour of an app repeatedly at low memory conditions. I want these low memory states to be reproducable.So runnly lots of websites in the background is not enough.
I've read the similar post on
How to test memory low condition on real iphone/ipad device (not simulator)?
Has anyone created a background app with this functionality?
Saving the memory state to file would be also useful.
The problem is, iOS will kill the background app before it notifies you that there is not enough memory. So you have to consume the memory within you app.
A way would be to repeatedly allocate memory over a amount of time (allocating it all at once will force iOS to kill your app afair).
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 am developing an Application for iPad & it consumes 5.5 MB at max on RAM of the iPad. I have ensured all this stuff using Instruments number of times. As soon as App uses little bit more memory, It throws memory warnings & app start behaving abnormally.
I have implemented the lines of code for freeing the memory in did-receive memory warning.
I also have ensured that NO LEAKS in the entire app.
I came to know that App needs at-least 6 mb memory.
Here is the general flow of the app.
log in -> 1st-list View -> 2nd-list view -> 3rd-list view -> 4th-Map & listview -> 5.Map&List
brief of each screen.
log-in - simple screen with username-pswd, making a web-service call & authenticating user
based on result of authentication, it will fetch few more data & list it on 1st-list View screen.
based on selection from 1st-list, app will load list on 2nd-list view
based on selection from 2nd-list, app will load list on 3rd-list view
based on selection from 3rd-list, app will load list & map will have pins relatively.
based on annotation from Map, app will navigate to another maps & different pins.
Here, app receives memory warnings on 6th screen. I have ensured all coding standards & all importance of all objects.
In Above case, All screens are very necessary, I am using Navigation Controller & just pushing view-controllers one by one. no duplications - ensured twice.
Now, the point is, App is being tested on iPad-1 with iOS 4.1 & all apps are forcefully closed before starting the testing of the app.
THOUGH, app receives warnings # just 5.5 mb usage.
I tried to convince my project managers that, this amount of memory usage is high & they are asking me - there should some option to set MEMORY. How this kind of High Graphics games & apps are running smoothly ?
I can't find appropriate document from Apple saying LIMIT. I have no answer to them.
If setting Memory limit is not possible, I am requesting you to provide Appropriate PROOF link, so that I can show it to my Project Manager.
If that kind of settings is possible, I am highly eager to know how to make that.
I doubt you will find any positive statement about memory limits for an app under iOS coming from Apple docs.
But if you google "ios app available memory" you will find a lot of information; e.g., this S.O. thread.
In my experience, my apps can sustain a "peak" memory usage of about 20MB (depending on the device state), but then memory use must quickly go well below the 10MB threshold for the app not to be killed (I would say that 6-8MB is more precise figure). Sometimes an app can be killed just because a peak cannot be "undone" fast enough.
One piece of information that might be useful for your managers is the output from the "Memory Monitor" tool in Instruments, specifically the "free physical memory". If you use it, you will invariably see that your app will be killed when the "free physical memory" goes below a given limit (as per Instruments output), approaching zero left memory.
Now, whether that limit is reached because you allocated some memory (which is reported by the Allocations or Leaks tools) or because of other factors (a framework loaded into memory? something in the iOS kernel or that is not tracked by Instruments?) you cannot know. But for sure you can follow how the free physical memory in the device varies over time with the use of your app.
Hope this helps.
The first generation iPad has a total of 256 MB of memory. Of course some of that will be used by the operating system itself.
It's very conservative to assume that at least 64 MB would be available for your application. So 6 MB sounds pretty minimal to me. There must be something your application is doing that causes more memory to be allocated.
There definitely isn't some "I'm a game let me use more memory option". All applications are allowed to use as much memory as they can (though it's always a good practice to minimize memory usage). If memory runs low, the application is notified, and if memory is exhausted, the foreground application is terminated.
If your application is terminated, examine the crash log to see how much memory it was using. My guess is that you'll find you are using more than you think.
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.
hi i just want to know this: When will iphone 3gs and iphone 4 send out memory warnings
i mean after how much memory our app uses does the both devices send warnings?
Thanks
You don't know when it will fire. You don't know how much memory is being used by other apps running in the background, Safari keeping webpages, etc. Pandora might be streaming in the background and it might be using a significant amount of memory. Don't count on any single amount of memory. Load lazily, and release uneeded allocations in didRecieveMemoryWarning.
If your app requires a lot of memory, some game developers tell their users to restart the device before playing to ensure the most memory for the app, and best performance.
It is not strictly defined but Apple suggests you don't use more than 24MB of graphical memory as overuse of graphical memory is typically why an application receives a low memory warning.
The only good way to manage critical low memory situations on the iPhone is to implement the didReceiveLowMemoryWarning delegate methods and release as much memory as possible at that point. This means for instance:
All non-visible images currently loaded in memory
All view controllers and their subviews if not in use
This can of course be done safely provided your application is able to reload that information at a later stage. didReceiveLowMemoryWarning is however a last resort situation for your application.
To avoid getting to that point it is recommended to only load resources lazily i.e. when and only when you need them, and release them when they are no longer needed (for instance implementing viewDidUnload on all your controllers).
I am writing an application that uses UIImagePickerController to take multiple pictures with the camera as fast as iOS allows. My application has to run on iOS 3.13 on all versions of iPhone hardware (v1 through 4). I am using UIImagePickerController with a cameraOverlayView.
My question is, how can I determine programmatically how many photos can be processed at once based on available memory? See below for more details. Any help is appreciated!
When the imagePicker delegate recieves imagePicker:didFinishPickingMediaWithInfo:, the delegate saves the full size image in the savedPhotosAlbum with UIImageWriteToSavedPhotosAlbum(). Once I have this problem solved, the app will be doing more things with the full size image.
As a test, I take pictures as fast as I can. Eventually, as expected, the app receives memory warning due to the large number of photos in memory while saving to the photo album. If I ignore the memory warnings and continue taking pictures, eventually the app is killed by iOS b/c of this.
I have no problem with setting a limit on the number of concurrent photos I allow the app to process at a time. Each iPhone HW version has different memory capacities and different camera resolutions. With iOS 4, multi-tasking may also effect the available memory. I'd rather do this programmatically than hard-code a limit based on HW version.
A test application that shows this behavior is at Source Code
It's easier to hard-code the limit.
There's no easy way to find out what the "available memory" is, since more memory may suddenly become free if there's a memory warning, or if the phone decides to kill various background apps (namely Safari). There's NSRealMemoryAvailable(), but that might just return the installed RAM (and is probably what [NSProcessInfo physicalMemory] uses).
You could try saving images in a queue — saving one image at a time is likely to use less memory. You can also add markers to your queue when you receive a memory warning, and disable image-saving when there's more than one (ideally you want to stop taking pictures if you get "level 2" or "level 3" memory warnings, but while these are printed to the console, I don't know any easy way of checking in code. Presumably you want to resume on a memory un-warning, but these don't exist either).
Also note that you can get the raw JPEG data (on some OS versions) through a notification; I forget what the name is, but the userInfo key is #"AVCaptureNotificationInfo_JPEGData". If you save the raw JPEG data, you might be able to process it later.
I think UIImageWriteToSavedPhotosAlbum() stupidly decompresses the JPEG returned by the camera and recompresses it, but I could be wrong. Camera images are only around 1-2 MB, so you ought to be able to take plenty without it crashing, but in my tests that's not the case.