Memory LEAK when using CCTextureCache::sharedTextureCache->addImageAsync(...)

char *fileName = new char[100]; sprintf(fileName, "%s_%s_Res.plist", pmModel->getPMName(), pmModel->getPMDirection()); char *textureName = new char[100]; sprintf(textureName, "%s_%s_Res.png", pmModel->getPMName(), pmModel->getPMDirection()); CCTextureCache::sharedTextureCache()->addImageAsync(textureName, NULL, NULL); //CCTextureCache::sharedTextureCache()->addImage(textureName); CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(fileName);

Everytime when using method “addImageSync”, I find that some memory leaks with the help of “Instruments”, the memory size is equal to the .png file I offer.
While I replaced this method with “addImage”, everything is OK.

BTW, I’m using the latest version 2.0.3 of cocos2d-x.

I’ve struggle a whole day for this problem… I just want to load the local resources in an asynchronous way…

Wait for help online. (在线等) THX!~


屏幕快照 2012-10-18 下午9.33.13.png (10.4 KB)

OK, I’m waiting for the reply.

have you tried calling autorelease() on the texture after being loaded?
i think i’ve read something about that having to made on the main thread, but i’m not sure…

I’ve actually asked about it and didn’t get any real answer about it, so try it out and good luck!

Xavier Arias wrote:

have you tried calling autorelease() on the texture after being loaded?
i think i’ve read something about that having to made on the main thread, but i’m not sure…
>
I’ve actually asked about it and didn’t get any real answer about it, so try it out and good luck!

Yep, I create the sprite with the method : CCSprite::createWithTexture, which returns an autorelease object.
The question is that everytime I use this addImageAsync, some memory which equals to the .png file’s size (not texture in memory) leaks.

I write to ask whether there is something wrong with this ImageLoading Method.

And thanks for your reply~ :slight_smile:

OK, does it mean that I have to use synchronous operation for texture/frames loading?
It does not work for a non-main thread loaing the resources. Because of opengl?

still waiting for help…

You may try like this:
CCTextureCache::sharedTextureCache()->addImageAsync(textureName, this, callfuncO_selector(LoadingScene::loadImageCallBack));

void LoadingScene::loadImageCallBack( cocos2d::CCObject* tex )
{
@ CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(fileName);@
}

You should call
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(fileName);
after the image has loaded.

waiter song wrote:

You may try like this:
CCTextureCache::sharedTextureCache()->addImageAsync(textureName, this, callfuncO_selector(LoadingScene::loadImageCallBack));
>
void LoadingScene::loadImageCallBack( cocos2d::CCObject* tex )
{
@ CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(fileName);@
}
>
You should call
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(fileName);
after the image has loaded.

I’ve tried this method, while it leaks some NSConcreteData, so I delete (char *)[data bytes] after image loaded, and solve this problem.

I think there exist bugs for cococ2d-x 2.0.3. The official demo which comes with cocos2d-x, when trying TextureCache example, you’ll find that everytime you click TextureCache(which will call addImageAsync), it leaks 136KB memory. 136KB = .png file’s size.

Hope this bug will be fixed in next version. THX~~

ruler zhang wrote:

waiter song wrote:
> You may try like this:
> CCTextureCache::sharedTextureCache()->addImageAsync(textureName, this, callfuncO_selector(LoadingScene::loadImageCallBack));
>
> void LoadingScene::loadImageCallBack( cocos2d::CCObject* tex )
> {
> @ CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(fileName);@
> }
>
> You should call
> CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(fileName);
> after the image has loaded.
>
I’ve tried this method, while it leaks some NSConcreteData, so I delete (char *)[data bytes] after image loaded, and solve this problem.
>
I think there exist bugs for cococ2d-x 2.0.3. The official demo which comes with cocos2d-x, when trying TextureCache example, you’ll find that everytime you click TextureCache(which will call addImageAsync), it leaks 136KB memory. 136KB = .png file’s size.
>
Hope this bug will be fixed in next version. THX~~
it seems they haven’t resolve this problem in github! Maybe they never found this topic.

C Zhang wrote:

ruler zhang wrote:
> waiter song wrote:
> > You may try like this:
> > CCTextureCache::sharedTextureCache()->addImageAsync(textureName, this, callfuncO_selector(LoadingScene::loadImageCallBack));
> >
> > void LoadingScene::loadImageCallBack( cocos2d::CCObject* tex )
> > {
> > @ CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(fileName);@
> > }
> >
> > You should call
> > CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(fileName);
> > after the image has loaded.
>
> I’ve tried this method, while it leaks some NSConcreteData, so I delete (char *)[data bytes] after image loaded, and solve this problem.
>
> I think there exist bugs for cococ2d-x 2.0.3. The official demo which comes with cocos2d-x, when trying TextureCache example, you’ll find that everytime you click TextureCache(which will call addImageAsync), it leaks 136KB memory. 136KB = .png file’s size.
>
> Hope this bug will be fixed in next version. THX~~
it seems they haven’t resolve this problem in github! Maybe they never found this topic.

Hi, with the help of my friend, I’ve solved this problem. Modify the cocos2d-x source code and make it!

ruler zhang wrote:

C Zhang wrote:
> ruler zhang wrote:
> > waiter song wrote:
> > > You may try like this:
> > > CCTextureCache::sharedTextureCache()->addImageAsync(textureName, this, callfuncO_selector(LoadingScene::loadImageCallBack));
> > >
> > > void LoadingScene::loadImageCallBack( cocos2d::CCObject* tex )
> > > {
> > > @ CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(fileName);@
> > > }
> > >
> > > You should call
> > > CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(fileName);
> > > after the image has loaded.
> >
> > I’ve tried this method, while it leaks some NSConcreteData, so I delete (char *)[data bytes] after image loaded, and solve this problem.
> >
> > I think there exist bugs for cococ2d-x 2.0.3. The official demo which comes with cocos2d-x, when trying TextureCache example, you’ll find that everytime you click TextureCache(which will call addImageAsync), it leaks 136KB memory. 136KB = .png file’s size.
> >
> > Hope this bug will be fixed in next version. THX~~
> it seems they haven’t resolve this problem in github! Maybe they never found this topic.
>
Hi, with the help of my friend, I’ve solved this problem. Modify the cocos2d-x source code and make it!

“I’ve tried this method, while it leaks some NSConcreteData, so I delete (char *)[data bytes] after image loaded, and solve this problem.” do you mean ,you solve it by this method?

C Zhang wrote:

ruler zhang wrote:
> C Zhang wrote:
> > ruler zhang wrote:
> > > waiter song wrote:
> > > > You may try like this:
> > > > CCTextureCache::sharedTextureCache()->addImageAsync(textureName, this, callfuncO_selector(LoadingScene::loadImageCallBack));
> > > >
> > > > void LoadingScene::loadImageCallBack( cocos2d::CCObject* tex )
> > > > {
> > > > @ CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(fileName);@
> > > > }
> > > >
> > > > You should call
> > > > CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(fileName);
> > > > after the image has loaded.
> > >
> > > I’ve tried this method, while it leaks some NSConcreteData, so I delete (char *)[data bytes] after image loaded, and solve this problem.
> > >
> > > I think there exist bugs for cococ2d-x 2.0.3. The official demo which comes with cocos2d-x, when trying TextureCache example, you’ll find that everytime you click TextureCache(which will call addImageAsync), it leaks 136KB memory. 136KB = .png file’s size.
> > >
> > > Hope this bug will be fixed in next version. THX~~
> > it seems they haven’t resolve this problem in github! Maybe they never found this topic.
>
> Hi, with the help of my friend, I’ve solved this problem. Modify the cocos2d-x source code and make it!
>
“I’ve tried this method, while it leaks some NSConcreteData, so I delete (char *)[data bytes] after image loaded, and solve this problem.” do you mean ,you solve it by this method?

No, this method can solve the problem, but it makes other problems.
I modify the autoreleasepool when adding image async, move the declaration to the “while” loop.

ruler zhang wrote:

C Zhang wrote:
> ruler zhang wrote:
> > C Zhang wrote:
> > > ruler zhang wrote:
> > > > waiter song wrote:
> > > > > You may try like this:
> > > > > CCTextureCache::sharedTextureCache()->addImageAsync(textureName, this, callfuncO_selector(LoadingScene::loadImageCallBack));
> > > > >
> > > > > void LoadingScene::loadImageCallBack( cocos2d::CCObject* tex )
> > > > > {
> > > > > @ CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(fileName);@
> > > > > }
> > > > >
> > > > > You should call
> > > > > CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(fileName);
> > > > > after the image has loaded.
> > > >
> > > > I’ve tried this method, while it leaks some NSConcreteData, so I delete (char *)[data bytes] after image loaded, and solve this problem.
> > > >
> > > > I think there exist bugs for cococ2d-x 2.0.3. The official demo which comes with cocos2d-x, when trying TextureCache example, you’ll find that everytime you click TextureCache(which will call addImageAsync), it leaks 136KB memory. 136KB = .png file’s size.
> > > >
> > > > Hope this bug will be fixed in next version. THX~~
> > > it seems they haven’t resolve this problem in github! Maybe they never found this topic.
> >
> > Hi, with the help of my friend, I’ve solved this problem. Modify the cocos2d-x source code and make it!
>
> “I’ve tried this method, while it leaks some NSConcreteData, so I delete (char *)[data bytes] after image loaded, and solve this problem.” do you mean ,you solve it by this method?
>
No, this method can solve the problem, but it makes other problems.
I modify the autoreleasepool when adding image async, move the declaration to the “while” loop.
so , do you confirm it is a bug , or it’s just because of your special using?

C Zhang wrote:

ruler zhang wrote:
> C Zhang wrote:
> > ruler zhang wrote:
> > > C Zhang wrote:
> > > > ruler zhang wrote:
> > > > > waiter song wrote:
> > > > > > You may try like this:
> > > > > > CCTextureCache::sharedTextureCache()->addImageAsync(textureName, this, callfuncO_selector(LoadingScene::loadImageCallBack));
> > > > > >
> > > > > > void LoadingScene::loadImageCallBack( cocos2d::CCObject* tex )
> > > > > > {
> > > > > > @ CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(fileName);@
> > > > > > }
> > > > > >
> > > > > > You should call
> > > > > > CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(fileName);
> > > > > > after the image has loaded.
> > > > >
> > > > > I’ve tried this method, while it leaks some NSConcreteData, so I delete (char *)[data bytes] after image loaded, and solve this problem.
> > > > >
> > > > > I think there exist bugs for cococ2d-x 2.0.3. The official demo which comes with cocos2d-x, when trying TextureCache example, you’ll find that everytime you click TextureCache(which will call addImageAsync), it leaks 136KB memory. 136KB = .png file’s size.
> > > > >
> > > > > Hope this bug will be fixed in next version. THX~~
> > > > it seems they haven’t resolve this problem in github! Maybe they never found this topic.
> > >
> > > Hi, with the help of my friend, I’ve solved this problem. Modify the cocos2d-x source code and make it!
> >
> > “I’ve tried this method, while it leaks some NSConcreteData, so I delete (char *)[data bytes] after image loaded, and solve this problem.” do you mean ,you solve it by this method?
>
> No, this method can solve the problem, but it makes other problems.
> I modify the autoreleasepool when adding image async, move the declaration to the “while” loop.
so , do you confirm it is a bug , or it’s just because of your special using?

Surely a BUG, you can try the official sample, click “CCTextureCache”, every time you click, it leaks some memory. NSConcreteData.

ruler zhang wrote:

No, this method can solve the problem, but it makes other problems.
I modify the autoreleasepool when adding image async, move the declaration to the “while” loop.

Hi!
Please confirm what exactly you did to fix the bug:
you moved this code into while loop?

CCThread thread; thread.createAutoreleasePool();

Oleksandr Dyedyk wrote:

ruler zhang wrote:
> No, this method can solve the problem, but it makes other problems.
> I modify the autoreleasepool when adding image async, move the declaration to the “while” loop.
>
Hi!
Please confirm what exactly you did to fix the bug:
you moved this code into while loop?
> `CCThread thread;

thread.createAutoreleasePool();`

Yes, actually. Why not have a try?

ruler zhang wrote:

Yes, actually. Why not have a try?
Already tried and it fixed the leak, thanks! :slight_smile:
(but i did not test it intensively, so was just reassuring)

Oleksandr Dyedyk wrote:

ruler zhang wrote:
> Yes, actually. Why not have a try?
Already tried and it fixed the leak, thanks! :slight_smile:
(but i did not test it intensively, so was just reassuring)

Hey, I did not test it intensively either. woo hoo hoo~.
However, nothing wrong has happened to me since I modified the method.

I wonder if it just leaking on IOS platform?

C Zhang wrote:

I wonder if it just leaking on IOS platform?

Android may not leak because of java GC?
I did not have a test.

I can confirm that there’s a bug in TextureCache loadImageAsync method, which will cause crashes, if your application is heavy on graphics and reloads resources between scenes. Android is not affected. I was really impressed seeing iPad2 crashing while htc wildfire worked properly.

Moving
CCThread thread; thread.createAutoreleasePool();
inside while loop in loadImage function in CCTextureCache.cpp fixes that issue, at least I can see no leaks in xcode tool and application works as expected.

Thanks to ruler zhang :slight_smile: