An iPad app I have been working on recently began being jettisoned by the OS for using too much memory. The annoying this was that there was no sign of leaks, and while running the app through the Allocations Instrument, there was no sign of excessive memory usage.

The app requires the main screen to have a large background image that changed as a UI control is modified by the user.

I checked the usual suspects – leaks, allocations and the stack traces therein. What I found was that there were several large blocks of memory being malloc'ed from within CoreGraphics, and that this memory appeared to have been allocated outside of the scope of the code I’d written:

Stack Trace

After a lot of tracing this problem, I found the culprit:

[UIImage imageNamed:@'Someimage']

Calls to this method cause the named image to be loaded into memory and cached. The image will remain in memory for the duration of your apps lifetime, and, if you have enough large images and calls to this function, they will cause the OS to jettison your program.

The Solution

Don’t use [UIImage imageNamed:@‘Someimage’] unless the image is small and you want to use it repeatedly in your app. Instead, the following snippet will allow you to load the image, then release it’s memory once you’re finished:

[UIImage imageWithContentsOfFile:path];

Note that imageNamed is not evil, it just needs some extra thought when using it. If there are enough images of a significant size, then the memory retained by this call may get your program forceably removed by the OS.