views:

240

answers:

3

I've observed similar behavior in an Apple example app and a game I am working on. In the game, the behavior is eventually causing the app to crash due to running out of memory. The example app is Touches.

At any point when touches are being tracked, which is when you're moving one of the objects around in Touches, and pretty much any time a touch is down in my game, memory usage goes up steadily, for as long as you continue moving the touch around. Once the touch sequence completes, the memory usage does not go back down. I've gotten Touches, which starts off using less than half a meg, up to about 4MB net allocations with a few minutes playing around. That memory is never deallocated.

So my question is: why does this memory never get deallocated? Am I fundamentally misunderstanding something? Is this a framework flaw? I've read some about issues with the accelerometer and touches leaking, but I'm not using the accelerometer at all in this game.

A: 

Use instruments to find what instances are not being deallocated. I had a similar problem, and all it came down to was that I was calling retain, but not release (due to a logic error).

Mr. Matt
I have been spending a lot of time in Instruments lately. Thing is, all the memory that ends up not being deallocated is stuff that is allocated and used inside of library calls. Things like CFSets used by the event handling infrastructure, or NSString objects that appear to be lying around from stringWithFormat: calls. How do I fix a problem like the event handling system not deallocating CFSet objects? I never have any access to those.
mythogen
Are you retaining these objects at all?
Mr. Matt
Are you retaining any of the touch event objects, or any object at all in your touch handlers?
Mr. Matt
No, I am not. I still get the memory problem even if I remove every line of code in the touch callbacks.
mythogen
+2  A: 

I apologize if this seems TOO elementary, but...

There's no chance you have NSZombiesEnabled set to YES, do you?

That would prevent the deallocation of any objects whatsoever, and if you did allocate new ones, then EVENTUALLY the app will run out of memory.

mmc
This is exactly what happened to me when I forgot that I'd left that environment variable set. Memory kept accumulating for all of those autoreleased touch objects.
Brad Larson
This seems to have been a major part of it. I turned off zombies and the memory usage improved. There's still a constant increase in memory usage though. Reconsidering the runs I did with Touches vs. the game, it seems like Touches did not have zombies on, and was still showing a steadily increasing footprint, but it wasn't holding on to the CFSet objects from the touch code. Now my code is behaving the same way with respect to the CFSet objects (only a few sticking around at any given time), but I'm still seeing an increased footprint over time.
mythogen
A: 

Im in a very similar situation. In fact, if i just let me app run without touching anything (all it does is run an NSTimer to update the display). And i notice the memory slowly but steadily increasing in usage.

If there are memory leaks its not obvious. Because ive seen memory leaks popup whenever it detects one.

So does that mean there are undetectable memory leaks?

Edward An
Yes. Keep in mind that a "leak" can be more than just objects no longer referenced. If you have an unbounded cache, that can increase memory use over time.
bbum
thanks for the hint (unbounded cache...gotta look that up!).
Edward An
bbum, nope. i dont get anything when i look around for "unbounded cache". could you please explain this? What are the rules for caching? I must be caching constantly right? Question is, where are my caches occurring and how to bound/release them?Now i do know that images loaded via [UIImage imageNamed] will cache the images. But im not loading them all the time, especially not when the app is just sitting there idly running - in which case all its doing is calling an image's drawAtPoint method.
Edward An