-1

Recently we noticed that we can load about 50 2448 x 3264 (iphone camera size) images into UIImageViews that are on the screen and currently visible. So all 50 images are decoded. We know on iphone memory size per app is about 500 MB (RAM and VRAM together). If we decode one 2448 x 3264 size image into RGB888 then it will be 24 MB, 50(image count) * 24(one image size) > 500 (memory for application) , so how it can be ? We run the instruments, selected blank then from library 'VM Tracker', and under 'IOKit'(there are the memory for textures) we saw that memory increasing not 24 MB but about 11.9 MB per image. We considering that may be iOS decodes jpeg files not to RGB888 but YUV420.

Can someone help us describe this situation ?

I can send code samples if there is the need for that.

Update: here is the simple project: https://www.dropbox.com/s/tg2r75jgzje57g8/ImageTest%202.zip?dl=0

There is the 2 images one encoded with simple jpeg algorithm in photoshop, another one is encoded with progressive algorithm. First one works as I said, you can scale image with pinch gesture, second one works as png files, loads 32 MB memory.

hsafarya
  • 993
  • 9
  • 21

2 Answers2

0

If you load a jpeg image into an UIImageView, iOS is smart enough to only decode as much data as necessary to display at the size required on-screen, which is probaby much smaller than the actual size of the image.

This isn't possible with other image formats such as PNG because they aren't stored as a sequence of progressivey higher-resolution data like JPEG - they can only be decoded at their original size (although you can downscale them yourself and then discard the original to save memory).

Nick Lockwood
  • 39,931
  • 11
  • 108
  • 100
  • But in that case, if I change frame of UIImageView iOS will load larger image. But it doesn't. Memory not changing. – hsafarya Jan 29 '15 at 18:57
  • In the example with progressive jpeg, UIImageView behave's like behaves like with png files: loads 32 mb memory. Change "standart_jpeg" with progressive_jpeg in the code. – hsafarya Jan 29 '15 at 19:21
0

There are a lot of things going on here, and the various (and changing) iOS optimizations are going to frustrate any attempt to get an absolute "this is exactly how much memory X will take."

First, to display an image in a UIImageView, you only need as much memory as the pixels require. You don't necessarily need a full RGB888 representation of all the pixels in the image at the same time. So you should be thinking about the size of of the screen, not the size of the image. Clearly you are not displaying 50x2448x3264 (400 million) pixels on an iPhone screen at the same time. There can be temporary spikes to do the decoding, but UIImageView can create a snapshot bitmap of the final result to work with. JPEG is particularly good at this because the format supports progressive loading. (Note that iOS has a special version of the PNG format that provides greater compression for things you copy into the app's Resources, so the size of a PNG can be smaller than you would think on an iPhone.)

(As an aside, this is why Retina iPads can have so much memory trouble. No matter how much you compress the image, in order to display it, you eventually need a full screen's worth of pixels.)

Next, parts of UIImageView memory are not necessarily "charged" against your app. They are stored in purgeable memory that the OS is free to throw away at any time. This has very important impacts on how your app behaves in low memory situations when you're suspended. Suspended apps are given no opportunity to respond to low memory and can just be killed. But the OS will dump purgeable memory for you, even when you're suspended, and so you are less likely to be killed for that.

If you're using imageNamed:, then you have even greater OS-level caching (i.e. not necessarily charged against you). And in some cases file data can be memory mapped to disk, avoiding real memory usage even for the raw data itself.

So for display purposes, experimentation is generally needed to get a sense of real memory requirements. It's very difficult to guess a priori how well iOS is going to optimize your problem.

Rob Napier
  • 250,948
  • 34
  • 393
  • 528
  • I have updated my question, in project there is the 2 jpeg files, one with simple jpeg algorithm, another with progressive , and progressive jpeg behaves as png loads 32 mb memory. – hsafarya Jan 29 '15 at 19:12