views:

89

answers:

6

I'm using Instruments with the Allocations instrument. I'm testing only a fixed interaction with my app.

I have a navigation controller which goes 4 stages deep. The first two stages are standard table view controllers and the last two are custom controllers with dynamically loaded images.

So I run my app in instruments (via Run with Performance Tool -> Allocations) and do the following interactions:

1.  App Loads
2.  I wait a bit until allocations graph stabilizes
3.  I tap/push into my navigation controller until the deepest level.
4.  I wait for the images to load and for the allocations graph to stabilize.
5.  I tap back out of the navigation controller until I'm back to the root level.
6.  I wait for the allocations graph to stabilize.
7.  GOTO 3.

Now what I've noticed is that between each iteration from 3 to 7 the allocations graph shows a slightly higher value. So the overall allocations are increasing even though I'm doing the same thing and all the view controller's deallocs are being called.

So the timeline looks roughly like this:

1.  Start: 1mb
2.  Push controllers/Load images: 4mb
3.  Pop controllers: 1.1mb
4.  Push controllers/Load images: 4.1mb
5.  Pop controllers: 1.2mb
6.  ... etc ... (always increasing slightly)

So my question is does this mean I have a leak or is this normal? Also what does the allocations graph data actually represent? And why is the value increasing even though I'm popping back out to the initial state? I'm worried that if my app runs long enough it will consume too much memory even though all the user is doing is pushing and popping view controllers.

Any thoughts would be helpful.

A: 

Yes, this is a leak. One of your view controllers along the line is missing something.

Joshua Weinberg
A: 

You probably have a leak. Check the leaks instrument which can help you find them.

cobbal
Thanks for the suggestion. You're right, using the leaks instruments I found out I have 3 leaks right from the get-go. I'll have to do some digging to see what's up exactly.
Nebs
A: 

If you are loading images then there is a good chance you are using [UIImage imageNamed:] that causes the system to cache and may be a cause of your memory use. But in short yes, you have a leak.

Shadow
Good point. While the image loading I was referring to doesn't use imageNamed I do in fact use imageNamed for my custom table cell and button background images. But I don't think this contributes to the overall allocations increase. Since imageNamed caches images wouldn't it avoid having to reload them on subsequent pushes/pops? Or does it work differently?
Nebs
I'm pretty sure that the imageNamed leak has been fixed
cobbal
+1  A: 

Is this in the simulator, or on the device?

As it's good to verify a problem exists on the device, as some system libraries release memory more often on the device than in the simulator.

If Leaks shows nothing, it's because you are still holding a reference to memory somewhere even if you don't think you are. To help track that down, highlight a small portion of the graph where the memory is increasing, and select "created and still living". Now you can see just the memory allocated, and start to track down just where the issue is.

Kendall Helmstetter Gelner
It's in the simulator. Thanks for the suggestion. Turns out I do have a leak, 3 in fact. I'll have to dig in a little deeper to see where exactly.
Nebs
+1  A: 

If you have the newest iPhone SDK, the version of Instruments it comes with (2.7 I believe) has a HeapShot feature. You can watch some of the WWDC '10 videos for more information, but essentially you take a shot the first time you pop controllers and then again when you pop a second time. It will show you any memory allocations that are different at the two moments.

jshier
Yeah I'm using the new SDK and instruments 2.7. This sounds like a cool feature, I'll def. check it out, thanks.
Nebs
The Heap Shot capability sounds just like what is needed for this kind of memory behavior. I've already used it to solve a similar problem.
Brad Larson