6
votes

I've recently faced some memory managing issue in my app.

The application takes advantages of some high-quality images and this extremely increases memory usage.

Here are some informations about the project and images details to make the issue more clear :

  • There are around 90 images added to my project. Half of them are designed in @2x size to support The New iPad Retina Display. So the maximum number of images for each devices is around 45.

  • Total size of Retina version of all images is around 25 MegaBytes ( Size of each indivisual image is variable from 10 KBs to 6.8 MB ). Meanwhile, size of all standards images equals to 11 MegaBytes.

  • The size of XCode archive of the project equals to 44 MegaBytes.

  • Maximum resolution of indivisual images in standard version of images is around 1500x4000 px while the minimum is around 60x60 px.

  • Maximum resolution of indivisual images in Retina version of images is around 3000x8000 px while the minimum is around 120x120 px.

  • Retina version of images have "@2x~ipad" suffix in their name while the name suffix for the others is "~ipad".

  • There's only one instance of most images is created during the app lifecycle.

  • Around 25 of the images are loaded during app launch and the rest are loaded during gameplay.

  • I've used [UIImage imageNamed:@"image_name.png"] wherever I want to load an image ( using [UIImage imageWithContentsOfFile] and [UIImage imageWithData] was extremely inefficient ).

But here is there problem :

When I trace the memory usage using Instruments I see that app's memory usage is extremely high. Here are the statistics of memory allocation's in different situations :

  • Allocated Memory on iPad 2 using standard images at startup : 58 MB

  • Allocated Memory on iPad 2 using standard images during Gameplay (when all images are loaded) : 131 MB

  • Allocated Memory on New iPad using Retina images at startup : 211 MB
  • Allocated Memory on New iPad using Retina images during Gameplay (when all images are loaded) : 470 MB

Any ideas why allocated memory is a lot higher than total size of images ?

2
Why are you loading all you images in memory? You should avoid using the UIImage imageNamed, and instead use UIImage imageWithContentsOfFile, as the later isn't loading the image permanently in memory.... Also if your images are huge, you should draw them in a CATiledLayer class, so that it draws them more efficiently to the screenLefteris
I'm loading all of images in memory because they all are needed before and during the gameplay. It's not following a usual design like other apps, and it's required to load those images. In other words I'm loading each image only when it is required, but the problem is that it's required for all of them to be loaded at startup :DSepehrom

2 Answers

0
votes

This is probably due to the fact that the images you use are compressed with png or jpg, and when decoded to memory are much larger in size than the original file size. It will take up something like width*height*4 bytes of memory no matter the image contents.

0
votes

a start would be to not use -[UIImage imageNamed:] for the images which fit any of the qualifications:

  • large sized
  • medium sized
  • "…only one instance…created during the app lifecycle."

but you need to pay attention to how those changes affect your program. you're currently relying on memory wherever possible. what i am suggesting is to shift some of those responsibilities to other areas. distribute the load so it still feels fast, but has a better balance of resources. once you use less caching, you will notice that you may end up reading and expanding some files more than one once. then try to figure out where you should share images you load. of course, load only what you need. then take what you learn and see ho it can be applied to the rest of your images.

also, break your images up -- you have images which are several times larger than the display's size. if they need to be that size, then break them up -- if they are only ever scaled down when presented, then resize them before distribution (e.g. so they require no scaling -- it will be much faster to display, look much better, and consume less memory).