Sunday, July 21, 2013

Cocos2D-X Memory Management

The last couple of days i have been trying to squash all the memory leaks in our game, this gave me a better understanding about the memory management used by cocos2d-x. It's a little different but with a little care you can get it right.

Here are a few facts you should know

  •  Every CCObject has a reference count of 1 when it is created.
  •  If you call autorelease() and dont' retain the CCObject you don't have to call release()
  •  CCNode's destructor calls release() on all its' children once(because it calls retain() in addChild())
  •  If you call retain() or new on a CCObject you have to call release() 


This is all straight forward, in fact this is all mentioned in the wiki on cocos2d-x.org website.
It gets' tricky when you start using CCTouchDispatcher's targeted delegate and the CCBReader.

When you load a ".ccbi" file the following happens:

  • CCBAnimationManager calls retain() on RootNode of the "ccb"
  • RootNode of the "ccb" calls retain() on CCBAnimationManager (it is set as userObject()).

so if the RootNode has to be deleted, CCBAnimationManager has to call release() on RootNode, but the CCBAnimationManager will be deleted only when RootNode calls release() on CCBAnimationManager. This is the cyclic dependency because of which both the RootNode and the AnimationManager stay in memory.

To counter this we have to create a wrapper class which keeps track of the CCBAnimationManager. Set the userObject in RootNode to NULL so that the CCBAnimationManager is no longer dependent on RootNodes's deletion. Check out the following link for full discussion.

The other most important thing is that, when you use CCB_MEMBERVARIABLEASSIGNER_GLUE(...) for accessing the children in the "ccb" files, it calls retain() on the member you get access to. So it's crucial to call release() on it in the destructor().


Post a Comment