Search code examples
c++memorycocos2d-x

Cocos2d-x CCSprite Memory Usage ( releasing CCSprite)


I'm developing a game in cocos2dx v2.2.3. I did a test and I found some problem as below:

Problem: (In windows) When I run my game and checking TaskManager, I found my game took ~20MB memory (in average).

But After Adding these lines of code in Init() of my game Layer and Then it increases the memory usage up to 300MB.

CCSprite *t;
t = CCSprite::create("Character/foo1.png");  //Each picture is about 50MB
t->release();
t = CCSprite::create("Character/foo2.png");
t->release();
t = CCSprite::create("Character/foo3.png");
t->release();
t = CCSprite::create("Character/foo4.png");
t->release();

( I myself create these picture huge for this test)

I also checked m_uReference when t->release(); is calling. and there m_uReference is becoming 0 and so It should be deleted! But why memory use is that high?

Question: I wonder How should I delete/remove/release a CCSprite after some time?


Additional Info/Test:

I found something that may help. After calling t->release(); It somewhere reach :

CCSprite::~CCSprite(void) {
    CC_SAFE_RELEASE(m_pobTexture);
}

But in CC_SAFE_RELEASE(m_pobTexture);, m_uReference of texture decrease from 2 to 1 and therefor the texture don't get deleted. I did a test and make this change :

CCSprite::~CCSprite(void) {
    CC_SAFE_RELEASE(m_pobTexture);
    CC_SAFE_RELEASE(m_pobTexture);
}

And RAM returned to ~20MB. ( Also I know This's not the correct way and I missing something else)


Solution

  • First, your code is likely to crash somewhere down the line (unless you left out some code): CCSprite::create returns an autoreleased CCSprite, which means you don't need to .release() it (and if you don't .retain() it, it's going to be deleted shortly after).

    For your question: CCSprite needs a CCTexture to works (your image is loaded in memory). But CCSprite don't own the CCTexture; the CCTexture is managed by CCTextureCache.

    CCTextureCache don't release a CCTexture directly when no CCSprite use it anymore: instead, it keeps the CCTexture for future usage (since loading a CCTexture is expensive) and only release CCTexture when there is not enough memory or you force it to do so, with

    CCTextureCache::sharedTextureCache()->removeUnusedTextures();
    

    The short answer is: you shouldn't worry about memory used unless you have a real memory problem (game crashing because of lack of memory). Games are supposed to use a lot of memory.