views:

2625

answers:

3

Ok......

I'm implementing a simple OpenGL ES application on the iPhone and I recently added in Pinch Media Analytics. Doing this helped uncover a memory management problem, and I'm not entirely sure how to deal with it.

In a perfect world, my application - which loads PNGs and .CAF files in didFinishLoading will launch, load all of it's resources, and run just fine.

HOWEVER, if my program gets a crash (which happened as I was integrating the Pinch Media libraries) or if I run Safari and open a bunch of pages and then launch my game, the game will crash back to the menu because it is out of memory.

This problem will persist until I do a hard reset of the system.

The default answer that you sort of get online is to implement the didReceiveMemoryWarning method as listed below....

- (void)didReceiveMemoryWarning
{ 
  // default behavior is to release the view if it doesn't have a superview.

  // remember to clean up anything outside of this view's scope, such as
  // data cached in the class instance and other global data.
  [super didReceiveMemoryWarning];
}

But this doesn't really help as it's the other programs that are holding onto memory not mine. I don't want to release my own view do I? Is there a good description of how to handle this situation and / or what happens in the didReceiveMemoryWarning event?

+1  A: 

If you only have a single view, then the only thing you can do really is to release any data you are not using, and lazy load them later.

If you have more than a single view, then they might be released if they are not visible. If this happens, the corresponding controller will be sent setView: with nil. I handle this happening by immediately releasing all IBOutlet variables so they are set properly when the view is loaded from its xib again.

This is the approach I take in a normal, non-OpenGL ES application which has >6 views, and works consistently even when I am 4 levels deep in a navigation view and all previous controllers have their views set to nil - there is no crash when I navigate backwards, though there is a delay as views are reloaded.

If you haven't found it already, in the simulator there is a menu item to simulate a memory warning, which is easier than forcing the condition to occur in a real device. That said, it does not replace testing the same scenario in a real device - just makes testing easier.

freespace
Thanks. I'll try the lazy load method as this only has one view.
K2Digital
+2  A: 

Welcome to the shared memory pool with no VM.... There's not a lot you can do here, but there are a few things (and it's possible it's actually your fault and you can completely fix it). Game developers often recommend their customers reboot before running them for this reason, so you may need to be in the same boat if you really need a lot of memory to be effective.

Of course you should try to minimize your own memory footprint. But you should also try to avoid excessive memory fragmentation. Sometimes the problem isn't that there's no memory; there's just no blocks large enough. Sometimes it's better to use a Mutable and keep modifying it rather than generating a new immutable object. This is particularly true of large NSStrings, which can really trash memory.

Keep in mind that UIImage +imageNamed: will keep the image around after you release it, so if you don't need them any more, you need to clear those out. Set its name to nil before releasing it to stop it caching.

Make sure to run your app under Instruments. You may be eating more memory than you think you are.

Don't forget the autorelease pool. If you generate a lot of autoreleased objects in a single event loop, you may need to drain your pool periodically so your don't spike memory. Memory spikes can lead to a program with modest memory requirements suddenly getting killed.

Rob Napier
Thanks Rob. I'll give that a shot.
K2Digital
A: 

You might try using compressed PVRTC instead of using PNG, to save some space (at a possible performance cost).

There's a nice little tutorial here:

http://iphonedevelopment.blogspot.com/2008/12/preparations-for-porting-nehe-lesson-06.html

And keep in mind you'll have to rewrite a few of your OpenGL calls to handle this different compressed texture.

[Disclaimer: I am not an OpenGL ES optimizing guru. Not by a looooong shot.]

Kevin L.