1

I'm really pulling my hair out on this one, it seems that I'm having severe issues with memory management on an iOS app.

Here's the case: first I load table. When the user taps a cell, it presents a complicated view. The most memory consuming about the view is that it's loading 20+ UIImages of 500x500. There are two other tabs in that view, loading a list of media (those UIImages, but then in a table) and another simple table.

When I return back to the first table view, apparently over 250 kB is still allocated on heap. I know the view is complicated, but there's no reason to keep so much memory alive. And well, guess what, when I do switch to the view a lot, eventually the app runs out of memory and gets killed.

What I tried to solve it:

  • Fix all Analyze issues, so according to that there are no leaks anymore.
  • Check all inits again for releasing, making use of autorelease where possible.
  • Checking all the memory leaks using Instruments -> Leaks. In a runtime of 6, I get not more than 2 or 3 leaks.
  • Last, Instruments -> Allocation, checking the heap. This is what bothers me, between two marked heapshots I get a difference of 250+ kB. I've looked into it, using the detailed views. I can't get my head around it: when it's pointing to one of my methods/classes, I'm pretty sure everything in there is either released or autoreleased. It's also pointing to a lot of not-mine (say QuartzCore) methods/classes.

Also, I don't understand why autorelease is not autoreleasing. I mean, it sometimes looks like an object that is marked for autoreleasing, is released way too late. I haven't created any NSAutoreleasePools myself, so is it possible that the pool is drained only when the runtime stops? How can I periodically drain the pool (even if it's not mine).

Any help is greatly appreciated.

Kind regards,

Reinder

Used this for the heap checking: http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/

Reinder de Vries
  • 522
  • 1
  • 6
  • 26

2 Answers2

2

Are you using imageNamed to load your images - this method will keep all images cached in memory. Try initWithContentsOfFile instead.

Watch out though; initWithContentsOfFile: won't cache at all so if you use this method a lot for the same image then you should be using imageNamed:!

deanWombourne
  • 38,189
  • 13
  • 98
  • 110
  • No, but thanks for the answer. All images are loaded from ~/Documents, using a subclass of `UIImage` that uses `initWithImage` which gets fed a `+UIImage imageWithContentsOfFile`. – Reinder de Vries Jan 17 '12 at 16:26
1

I think you might want to try to optimize your design first and read guides for efficent memory management. A better understaning of the components and the runtime helps more than tracking memory allocations and will make it easier to find the leaks.

  • First you should always use release. Only use autorelease when necessary.
  • Make sure you follow the guidelines for UITableView implementations and efficient management of UITableViewCells (lazy loading, cell reusing etc.).
  • Check if you have retain-cycles (retained view controllers won't be deallocated).
  • Track the deallocation of your view controllers and objects
  • Don't keep stuff in memory you don't need anymore.
  • Don't load stuff you don't need right now.
CodeStage
  • 540
  • 4
  • 6
  • Okay, I've tried ARC and the memory leaks remain. I'm thinking the whole issue is about those retain-cycles. Strong references between objects, that thus never get released. How can I circumvent this? From: http://stackoverflow.com/questions/6260256/what-kind-of-leaks-does-objective-cs-automatic-reference-counting-in-xcode-4-2 – Reinder de Vries Jan 17 '12 at 19:35
  • I'm pretty sure it's retain cycles. I'm reading up on Apple's Advanced Memory management and, hate to admit it, I've built references between classes like Document <-> Page and Page <-> Document. Thanks for the advice, and back to the drawing board ;-). See: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html – Reinder de Vries Jan 17 '12 at 19:44
  • Okay, to be conclusive. Child classes (such as Page) should have a weak reference to their parents (Document). Parent classes (Document) should have a strong reference to their children (Page). A strong reference in my case resembles a (nonatomic, retain) property, where a weak reference resembles an (assign) property. I've been using "delegate"-like objects to notify a parent object, using the (nonatomic, retain). I think that should be @property (assign). To future generations: know your retain/release. – Reinder de Vries Jan 17 '12 at 19:50