ImageIO dirty memory is not automatically cleared by iOS

ZAN picture ZAN · May 6, 2013 · Viewed 13k times · Source

I am creating an application which is a kind of gallery - it shows different media content as a fullscreen viewer. Allocations instrument shows that Live Bytes parameter doesn't grow higher than 40 Mb when using application. Meanwhile the app is 100% being killed after I slide pages 20-30 times. I checked Dirty Memory parameter and found it was 10 times bigger than Live Bytes size. And the most of that dirty memory consumed Image IO:

Screenshot

EDIT, another screenshot:

Screenshot

The allocations peaks above are switching video/image media contents. The problem is the dirty memory grows almost linearly and I need to release it somehow.

Now about application design. Application screen has one horizontal scroll view. Scroll view contains videos or collage objects which contain multiple images. To save memory only three pages are created at a time - current page and pages on the left/right. So pages always created and removed on-fly when sliding scroll view.

All the images I load using [UIImage imageWithContentOfFile: path] method. Collage object stores UIImage instances inside imagesArray. In dealloc method imagesArray attribute is cleared.

So, questions:

  • Is it a kind of system bug in [UIImage imageWithContentOfFile?]
  • Is it Image IO cache?
  • Can I clear it?

Answer

David H picture David H · May 7, 2013

Putting this here as too big for a comment, just some ideas:

1) one way to retain objects by mistake is to have objects in views that get hidden but not removed from their superview (and thus stay retained)

2) if you do anything with UIImageView etc on any thread not the main thread bad things can happen (like this)

3) copy your project so you can freely mess with it, and try a bunch of things:

  • instead of multiple images, always load the same image, but leave the other parts of your code as they are - do things change?

  • In any subclasses you create that would hold/retain images, put a log message in the dealloc to see if in fact those objects are getting dealloced.

  • subclass UIImageView, use it for the images, and log the dealloc

  • subclass UIImage, use it for these images, log the dealloc

4) I am having a hard time believing imageio has a defect that would do this, but what you could do is switch to using imageWithData, and load the data yourself. Use the F_NOCACHE flag when you actually read the data - there is other code on SO on how to do this, you can search on it (I answered a question on it).

If you can create a demo project with this defect, it would be a lot easier to debug it than just guess at what to do. Logging the class that gets dealloc'd goes a long way, since you will see immediately what is not getting released, and then better focus in on the problem.