Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does iOS terminate my app even when I free lots of memory in response to memory warnings?

I can't figure out why iOS is terminating my app (iPad, iOS 4) due to memory usage even after I free a ton of memory in response to low-memory warnings. For example, here's a typical termination scenario, with me logging memory usage every so often -- look at the "app" usage, the first KB value on each line:

...
2011-12-14 13:25:42.343 Oyster[211:707] Memory usage (KB): app 268256, delta 6472, used 366800/373940
2011-12-14 13:25:43.292 Oyster[211:707] Memory usage (KB): app 273900, delta 5644, used 372444/381024
2011-12-14 13:25:44.159 Oyster[211:707] Memory usage (KB): app 282920, delta 9020, used 381464/389116
2011-12-14 13:25:45.184 Oyster[211:707] Memory usage (KB): app 272140, delta -10780, used 370684/379432
2011-12-14 13:25:46.109 Oyster[211:707] Memory usage (KB): app 260412, delta -11728, used 358956/365900
2011-12-14 13:25:48.443 Oyster[211:707] Received memory warning. Level=2
2011-12-14 13:25:48.454 Oyster[211:707] Memory usage (KB): app 9172, delta -251240, used 107716/112548
(gdb)

You can see app memory usage increasing till it gets a memory warning. Then I correctly respond to the memory warning and free a bunch (250MB!) of memory. At that point my app is terminated and iOS goes to the iPad home screen.

The "Memory usage" logs here are displayed with my logMemoryUsage() function which is based on code from this answer.

For the record, I'm using SDWebImage to cache UIImages in memory, but as shown, it handles memory warnings by emptying its cache (rather large at this point). I realize I could tweak SDWebImage's caching to not fill all available memory and just wait for memory warnings, but that begs the following question...

Why is iOS terminating my app, even though I'm responding to memory warnings by happily freeing a ton of memory?

like image 354
Ben Hoyt Avatar asked Dec 14 '11 19:12

Ben Hoyt


People also ask

How much RAM can an iOS app use?

iPadOS 15 Allows Apps to Use Up to 12GB of RAM on High-End iPad Pro, Up From Just 5GB. In June, we reported that starting with iPadOS 15, Apple is giving developers the ability to allocate their apps more RAM, allowing apps to use more of the available memory in the iPad to run faster and smoother.

How much memory should an app use?

Typically, individual apps can use between 40MB – 1GB of phone storage. If you anticipate downloading just a few key apps and the odd game, then 5GB of storage space should be plenty. If you are a pro gamer and plan to download 200+ apps and large games, then you will require 50GB of phone storage.

What are the ways to let your app consume less power consumption and less memory consumption iOS?

Techniques for a lower memory footprint.Load images incrementally using Image/IO. Downsampling with Core Graphics. Download smaller images. Managing Caches.

How much RAM does my app use?

Tap Developer options and then tap Memory. In the resulting screen (Figure B), you'll see a list of the average memory used by the device in the past three hours (you can adjust the time frame, by tapping the time drop-down at the top). The Memory usage window in Android 12.


2 Answers

This is kind of a general answer for good practices wrt memory management etc. Generally, sounds like the in-memory cache is simply getting way too big and even though it releases objects in response to memory warnings, by that time it's too late.

  1. Memory warnings are not inherently "bad" and you cannot avoid them. They are a normal part of an iOS life cycle and you must handle them correctly by releasing all non-essential data in all of your objects to assure your app behaves responsibly. Even if your app has a small footprint you could still get a memory warning b/c of other conditions on the device in question (e.g. other apps in use, etc). I'm referring to the runtime notification UIApplicationDidReceiveMemoryWarningNotification here. The debugger messages (e.g. "Received memory warning. Level=2") are specific to your app though they don't necessarily correlate to receiving a runtime notification.

  2. I don't know much about SDWebCache. I would look at the implementation and ensure it is efficiently releasing memory. For example, maybe using @autoreleasepool in relevant places would help it release objects more efficiently within a run loop.

  3. You should strive to keep your app's in-memory footprint is as constrained as possible. it's fine to use an in-memory cache for image data but I would limit its size. If your app's footprint gets > 250MB I'm not surprised it is being terminated, even if you handle memory warnings. It's likely too late by then.

  4. Your could have other issues causing/contributing to the termination. As the comments have suggested, you need to do more debugging in instruments to look for leaks, bad access, etc. Posting the crash log here would be helpful.

like image 177
XJones Avatar answered Nov 15 '22 22:11

XJones


Without more information I can't know if these apply to you, but I have commonly run into certain issues after trying to clean up memory warnings:

  • Unknown circular references prevent the memory from being freed like you expect. Use Instruments to look for them. I recently fixed a case in which I was accidentally using self within a block, causing a retain. We noticed it when there was a memory warning, and we couldn't recover from the warning well by releasing that resource.
  • Cleaning up resources – or an automatic release of resources – has released something that is still needed. You may have a nil where you do not expect one, or you may operate on a zombie. Check your retention and clean-up, especially the nilling of delegates. Turn on zombies and an exception breakpoint.

Usually the best resolution is to prevent the memory warning from occurring in the first place.

like image 29
Peter DeWeese Avatar answered Nov 15 '22 21:11

Peter DeWeese