What level of memory usage will trigger iOS's memory warning? - ios

My app may consume tens of MB of memory, and in rare cases it reaches 100MB. Do I need to worry about memory warnings and implement didReceiveMemoryWarning()? And how much time do I have to release memory? (I need to persist the data in memory to the hard drive.)
Suppose I target devices after iPhone 5.

First off, here's the discussion of the method didReceiveMemoryWarning from Apple docs.
DISUCSSION
Your app never calls this method directly. Instead, this method is
called when the system determines that the amount of available memory
is low. You can override this method to release any additional memory
used by your view controller. If you do, your implementation of this
method must call the super implementation at some point.
As per this reddit thread, even if you handle this event, your application can still be terminated to give space to the running applications. Also, often times all of the apps' didReceiveMemoryWarning on the device are invoked, not only yours.
I hope this answer is okay since this seems just a comment quoting the documentation :)

Related

didReceiveMemoryWarning: what type of memory?

I have a base cordova app, with some objective-c code around cordova's framework. Sometimes I've didReceiveMemoryWarning notification, but I don't understand if the problem is the javascript inside the UIWebView or other.
The documentation says:
Your app never calls this method directly. Instead, this method is called when the system determines that the amount of available memory is low.
But my question is: what type of memory?
RAM? Heap allocations? Something else?
RAM, it is for RAM, if your app consuming more memory without realising it, and no memory to remain to process any more thread then, this didreceivememorywarning get called by system.
You should profile your app with Instruments and you'll get a better picture of what's consuming memory.
The memory issue represents to RAM, generally we are creating the app using different objects, and these objects take some memory to process the required task. If we aware about them we can easily manage the memory but sometimes for beginners it is not managable to debug the memory, and didReceiveMemoryWarning occured. We can diagnose or debug this issue by instruments.

What are the best ways to avoid Out of memory issues in iOS?

I am working on one application which has lots of screens, custom views and API calls on almost each screen. Sometimes when the user uses the app for a long time, it gets crashed because of Out of Memory issues.
Ideally, I followed all guidelines while developing app and ARC takes care of memory usage. So what are the best way to avoid such memory issues?
Code has a built-in memory profiler that can help you with this issue - for a tutorial on how to use it, this might be helpful http://www.raywenderlich.com/23037/how-to-use-instruments-in-xcode
Otherwise, if dealloc isn't being called it could be a symptom of a retain cycle (two objects maintain strong references to each other, so they are never deallocated).

How to implement didReceiveMemoryWarning in Swift?

Whenever I create a new View Controller subclass, Xcode automatically adds the method
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated
}
Usually I just delete it or ignore it. This is what all the tutorials I have seen do, too. But I assume that since Xcode gives it to me every time, it should be somewhat important, right? What should I be doing here? I assume that disposing of resources means setting them to nil, but what exactly are "resources that can be recreated"?
I have seen these questions:
How to implement didReceiveMemoryWarning?
UIViewController's didReceiveMemoryWarning in ARC environment
iPhone Development - Simulate Memory Warning
But they are all pre-Swift. Although I don't know much about Objective-C, I have heard that the memory management is different. How does that affect what I should do in didReceiveMemoryWarning?
Other notes:
I am fuzzily aware of Automatic Reference Counting and lazy instantiation
The documentation on didReceiveMemoryWarning that I found was rather brief.
Swift
Swift uses ARC just like Objective-C does (source to Apple Docs). The same kind of rules apply for freeing memory, remove all of the references to an object and it will be deallocated.
How to free memory
I assume that disposing of resources means setting them to nil, but what exactly are "resources that can be recreated"?
"resources that can be recreated" really depends on your application.
Examples
Say you are a social media app that deals with a lot of pictures. You want a snappy user interface so you cache the next 20 pictures in memory to make scrolling fast. Those images are always saved on the local file system.
Images can take up a lot of memory
You don't need those images in memory. If the app is low on memory, taking an extra second to load the image from a file is fine.
You could entirely dump the image cache when you receive that memory warning.
This will free up memory that the system needs
You are creating an amazing game that has a number of different levels.
Loading a level into your fancy game engine takes a while so if the user has enough memory you can load level 3 while they are playing level 2.
Levels take up a lot of memory
You don't NEED the next level in memory. They are nice to have but not essential.
LevelCache.sharedCache().nextLevel = nil frees up all that memory
What shouldn't you deallocate
Never deallocate the stuff that is on screen. I've seen some answers to related questions deallocate the view of the UIViewController. If you remove everything from the screen you might at well crash (in my opinion).
Examples
If the user has a document open that they are editing, DON'T deallocate it. Users will get exceptional angry at you if your app deletes their work without ever being saved. (In fact, you should probably have some emergency save mechanism for when that happens)
If your user is writing a post for your fabulous social media app, don't let their work go to waste. Save it and try to restore it when they open the app again. Although it's a lot of work to setup I love apps that do this.
Note
Most modern devices rarely run out of memory. The system does a pretty good job of killing apps in the background to free up memory for the app running in the foreground.
You have probably seen an app "open" in the App Switcher yet when you tapped on the app it opened to its initial state. The OS killed the app in the background to free up memory. See State Restoration for info on how to avoid this problem.
If your app is getting consistent memory warnings when you aren't doing a huge amount of processing make sure that you aren't leaking memory first.
Detecting memory leaks is outside the scope of this answer. Docs and a tutorial.
When didReceiveMemoryWarning is called, it means your app is using too much memory (compare with memory of device), and you should release any additional memory used by your view controller to reduce the memory of your app. If the memory app gets over the memory of device, iOS will kill your app immediately. "resources that can be recreated" means somethings you can recreate it again at somewhere, you don't need them now (don't need to put them in the memory). And you can release it when get didReceiveMemoryWarning.
Here is another detail topic: ios app maximum memory budget

How much memory can an iOS app allocate?

I'm trying to get a feel for the amount of memory an iOS app can reliably allocate to help me drive some design decisions. The app is going to involve real time synchronised processed audio and animation.
Other than writing code that loads up the frameworks I'll need then trying to progressively allocate memory until I get warnings, is there any way to determine this kind of thing?
The simulator doesn't let you select a specific hardware model, so I assume I can't even simulate this stuff.
You cannot determine how much memory an app allocate as far as I know. Always try to keep the lowest memory possible for your app.
The memory allocated to your app depends on many factors like : number of background process happening, amount of memory available, memory used by other apps, the device you are running etc..
So, its not a good practice to keep a maximum line for memory consumed by your app and design accordingly.
Also try to hold only the necessary memory you need and handle memory issue in the memory callback methods like 'didreceivememorywarning'. Always consider that you have the least amount of memory allocated by the OS.

iOS : ARC, not freeing memory

I've kind of a weird issue with my iOS app.
after a while my app goes low in memory so memory warning, everything seems to be fine, but when I check the memory usage I noticed that all the calls to viewDidUnload didn't free up lot of memory, so after a few click in my app, it goes again in memory warning, everything seems to be fine again, but not a lot a memory have been released, so it goes again in memory warning faster, and then it crash (after the third memory warning most of the time). this crash is random : app freeze, app leaves, my debugger says app paused, but no bad access or sigbort, no zombies.
my guess is that memory warning can't free up enough memory has it should.
(I checked all my viewDidUnload and make nil every objects that are allocated in viewDidLoad)
Any help will be usefull !
thanks a lot.
So I managed to work with my issue.
I wrote "-(void) dealloc" methode in all my controllers and check if I enter in it as I should. (on pop controller, dissmiss etc..)
Every time it didn't, I do step by step in the controller to see what was retaining my controller from beeing dealloc.
most of the time it was some property that was not in "unsafe_unretained"
delegate that was in "ASSIGN" (and should not be in assign but in unsafe_unretained)
(heritage from non-ARC project...)
I also had some strange controller with XIB that was not deallocated even if empty.
I rebuild new one step by step with copy/paste and finaly with exactly the same code, the new controller was released, with no visible difference between then !!! gnneee
at least I know how to debug that kind issues now...
I don't think there's any way to give a specific answer without more data so the best I can do is suggest that you stop guessing what might be happening with your app and learn how to measure what is actually going on. Run your app under Instruments and you'll be able to check for leaks and also actually see what classes are responsible for the most of your application's memory footprint.
You should make sure you know how to use both the Leaks instrument to identify leaked object but also the Allocations instrument to identify orphaned (but not leaked) sets of objects which should have been released or just cases where your app is not responding to memory warnings as you expected.
https://developer.apple.com/library/ios/#documentation/developertools/conceptual/InstrumentsUserGuide/AboutTracing/AboutTracing.html might be a good place to start and there are a number of tutorials available as well; http://www.raywenderlich.com/2696/how-to-debug-memory-leaks-with-xcode-and-instruments-tutorial and http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/ are among the first results I saw.
Vassily,
First, if you aren't yourself releasing extra memory, the the -didReceiveMemory warning does you no good and the OS will keep asking for memory until you are killed. This sounds like it is your problem.
Second, if that isn't the problem then you are probably getting terminated due to the size of your resident memory partitions. Make sure you look at your VM allocation in Instruments. I expect the MALLOC_TINY or MALLOC_SMALL both have greater than 5 MB resident and dirty footprints. Due to the nature of small allocations these VM regions will never shrink. The only option you really have is to not create a lot of small items in the first place. This is really only something you can address by changing you code's algorithms to use less memory.
Andrew

Resources