views:

531

answers:

3

I would like to handle out of memory errors in iPhone to execute logic with lesser memory requirements in case I run of of memory. In particular, I would like to do something very similar to the following pseudo-code:

UIImage* image;
try  {
    image = [UIImage imageNamed:@"high_quality_image.png"];
} catch (OutOfMemoryException e) {
    image = [UIImage imageNamed:@"low_quality_image.jpg"];
}

First I attempt to load a high-quality image, and if I run out of memory while doing it, then I use a lower quality image.

Would this be possible? Is there some kind of exception or notification than can be handled when an out of memory error occurs?

The out of memory warning is not what I'm looking for, as it's received before the phone runs out of memory. I would like to know if the logic I'm executing failed because an out of memory error, and deal with this accordingly.

Alternatively, something like this could also help:

UIImage* image;
if (enoughMemory) {
    image = [UIImage imageNamed:@"high_quality_image.png"];
} else {
    image = [UIImage imageNamed:@"low_quality_image.jpg"];
}
A: 

The iPhone has a low memory warning that is triggered when a certain memory threshold is reached. This callback is issued to the application and must be responded to appropriately or your application runs the risk of being preempted by the OS. At that time, then, it would be good for your application to convert the high-memory images to more low memory ones.

Be careful here, though, as the size of the file on disk is not necessarily representative of how much memory it will consume once it has been loaded and prepped for use on the device.

See here for more information on handling low memory warnings.

fbrereto
Thanks for the swift reply. That would be a bit different. The low memory warning is called before the phone runs of out memory, and I can release memory if needed. In this case, I want to know if the logic I'm executing failed because it ran out of memory.
hgpc
Have you tried pushing the device to the memory limit in the fashion you suggest? I'd think how it responds would dictate the steps you should take to get the behavior you're looking for.
fbrereto
Yes, the app closes.
hgpc
A request for a large amount of memory simply kills the app? That sounds a bit hardcore. Perhaps there is an exception being thrown or some other notification that is unhandled? Anything being output to the console when that happens?
fbrereto
If such an exception or notification can be handled is precisely what I'm asking. The console outputs: Program received signal: “0”.
hgpc
That case cannot be handled. The only chance you get is the memory warning in your view controllers. Once your application reaches that critical point, the OS will kill it regardless. There's nothing you can do except release some memory when the system tell you to.
Jasarien
I guess Joo Park's answer is the only viable option then.
hgpc
A: 

Edit: it looks like this wasn't quite the answer to your question.


What are you trying to do with your images? Some actions, like storing a full-sized image returned from the image picker controller are particularly heavy memory users.

What I would recommend doing is always assuming you need the smallest sized images at all times and:

  1. If you will need a high-resolution image later, cache it to disk.
  2. All images for display should be the minimum resolution you can get away with.
  3. When you need the high-resolution image, pull it back out of the cache.
  4. Use the low memory warnings as a sign to release any images that you have in memory, but aren't visible.

Now, it's possible that this situation won't work for you. Reading and writing large images to disk on the iPhone is slow. If that's the case what you'll have to do is follow @fbrereto's suggestion: load the large image, watch out for memory warnings and if you get one, drop it and load the small image.

You definitely shouldn't ignore memory warnings, but not responding to one won't necessarily crash your app. My iPhone 3G will get memory warnings almost every time I get an image back from the UIImagePickerController, and there's nothing I can do about it.

kubi
I'm not ignoring memory warnings. I always release resources when I get them. But sometimes I do run out of memory anyway, and I would like to deal with that case as well.
hgpc
+1  A: 

here is an answer that will get you the current memory used by your app and you can decide what to do based on that info.

http://stackoverflow.com/questions/2786539/iphone-memory-usuage

Joo Park
Thanks Joo. Is it possible to know how much memory you have left?
hgpc
take the number you get from that code and subtract from 24 megabytes. I think 24 megabytes is the max that apple will allow per app thats running.
Joo Park
Is there a constant with such value? Most likely the various generation iPod touch and iPhone and the iPad don't have the same max.
hgpc