safeDelete problem with 1.4?
by Django Zeaman · in iTorque 2D · 10/21/2010 (10:33 pm) · 25 replies
We fixed the intro movie issue with 1.4, but now we noticed a new performance issue: some of our graphics aren't deleting properly, so we have memory creep and leaks with each wave. Our game, used to run for hours and hours, not it crashes after 40 waves.
Just wondering if anyone else is having any problems with graphics not releasing out of memory after switching to 1.4 from 1.3.
Just wondering if anyone else is having any problems with graphics not releasing out of memory after switching to 1.4 from 1.3.
About the author
I worked in learning simulations, then spent a few years working at Apple. I started to think about creating games for the iPhone and left to do that last summer. Our first game is coming out this summer.
Recent Threads
#2
10/22/2010 (8:02 am)
You could try using delete instead?
#3
10/22/2010 (12:44 pm)
Aye, scheduling delete is pretty much what safedelete does iirc :)
#4
Anyone else had issues with graphic objects not dealloc'ing from memory?
10/24/2010 (10:14 pm)
Just tried delete instead of safeDelete - got the same gradual memory creep per wave. So that doesn't seem to be making the difference.Anyone else had issues with graphic objects not dealloc'ing from memory?
#5
But didn't back in July prior to moving to SDK 4.
Is it possible that the iTorque engine is not playing nice with the new SDK in terms of releasing memory?
We've done pretty extensive testing the past 3 weeks on this issue solely and come to a brick wall. Any ideas or suggestions most welcome.
10/25/2010 (8:30 pm)
Okay, tried 1.3 as well and having same issue.But didn't back in July prior to moving to SDK 4.
Is it possible that the iTorque engine is not playing nice with the new SDK in terms of releasing memory?
We've done pretty extensive testing the past 3 weeks on this issue solely and come to a brick wall. Any ideas or suggestions most welcome.
#6
Have you checked for leaked memory using the Instruments tool?
10/25/2010 (8:33 pm)
Given the information supplied it is nigh on impossible to diagnose this.Have you checked for leaked memory using the Instruments tool?
#7
I am having memory problems (serious ones) but with the iPad, iPhone seems fine. This is using 1.4 and TBH I'm not getting a good feeling about it at all - low memory warnings are constantly coming my way and this is on iOS 3.2, dreading to think what the situation will be with 4.2 :(
One important thing to remember is that deleting a datablock doesn't remove the underlying image - you need to call delete on the imageMap as well if you want to free up the image memory.
10/25/2010 (9:27 pm)
Did you try putting break points on the safeDelete / delete functions and see if the object memory is freed?I am having memory problems (serious ones) but with the iPad, iPhone seems fine. This is using 1.4 and TBH I'm not getting a good feeling about it at all - low memory warnings are constantly coming my way and this is on iOS 3.2, dreading to think what the situation will be with 4.2 :(
One important thing to remember is that deleting a datablock doesn't remove the underlying image - you need to call delete on the imageMap as well if you want to free up the image memory.
#8
We noticed crashing when we got to wave 40 or so, in the memory leak tool we can see that the amount of the leaks and the live memory bytes is going up based on the number of runners. About 100kb per runner.
We stripped it down to just a still graphic appearing and then deleting (no pathfinding, no attacking from "towers" etc.) - still get memory leak and gradual live memory creep. It's much smaller, but it is still there. But we had same code working with 1.3 and SDK 3.x. We just ran test with iTGB 1.3 and had same results...so we're wondering if something happened with the way memory is deallocated with iTorque and SDK 4??
I'd be happy to provide any other data that would be helpful to diagnose. Really appreciate your response.
10/25/2010 (10:22 pm)
Craig - yes, we've been using memory leak on instruments. The game is a tower defense game, each wave has several runners who come out and must be defeated, as usual for the genre.We noticed crashing when we got to wave 40 or so, in the memory leak tool we can see that the amount of the leaks and the live memory bytes is going up based on the number of runners. About 100kb per runner.
We stripped it down to just a still graphic appearing and then deleting (no pathfinding, no attacking from "towers" etc.) - still get memory leak and gradual live memory creep. It's much smaller, but it is still there. But we had same code working with 1.3 and SDK 3.x. We just ran test with iTGB 1.3 and had same results...so we're wondering if something happened with the way memory is deallocated with iTorque and SDK 4??
I'd be happy to provide any other data that would be helpful to diagnose. Really appreciate your response.
#9
Sorry, probably something basic we're missing.
We have a runner object on top of a background. We create and delete these runners hundreds of times over the course of a level. The problem is that deleting them is not freeing up memory, so they are accumulating in live memory and crashing the game.
So here is the KillRunner function:
function KillRunner(%runner)
{
if (!isObject(%runner))
return;
SaveAchivStudentsDefeated(%runner.runnerType);
TryAchivStudentsDefeated(%runner.runnerType);
%bNextWave = false;
if (%runner.lastOne)
%bNextWave = true;
TryToReleaseFromWishList(%runner);
%runnerAnimObj = %runner.animObj;
%healthBarObj = %runnerAnimObj.healthBarObj;
%healthBarBG = %healthBarObj.bgObj;
PlayRunnerDeathSound(%runnerAnimObj.runnerType);
%runnerAnimObj.Delete();
%healthBarObj.Delete();
%healthBarBG.Delete();
%runner.Delete();
if (%bNextWave)
StartNextWave();
}
10/25/2010 (10:49 pm)
Scott - Can you share a little more detail on what you mean by "call delete on the imageMap as well if you want to free up the image memory"?Sorry, probably something basic we're missing.
We have a runner object on top of a background. We create and delete these runners hundreds of times over the course of a level. The problem is that deleting them is not freeing up memory, so they are accumulating in live memory and crashing the game.
So here is the KillRunner function:
function KillRunner(%runner)
{
if (!isObject(%runner))
return;
SaveAchivStudentsDefeated(%runner.runnerType);
TryAchivStudentsDefeated(%runner.runnerType);
%bNextWave = false;
if (%runner.lastOne)
%bNextWave = true;
TryToReleaseFromWishList(%runner);
%runnerAnimObj = %runner.animObj;
%healthBarObj = %runnerAnimObj.healthBarObj;
%healthBarBG = %healthBarObj.bgObj;
PlayRunnerDeathSound(%runnerAnimObj.runnerType);
%runnerAnimObj.Delete();
%healthBarObj.Delete();
%healthBarBG.Delete();
%runner.Delete();
if (%bNextWave)
StartNextWave();
}
#10
@Scott: For some reason I had it in my head that when you delete datablocks that have nothing referencing them that will also cleanup the memory related to the graphics (ie imagemap) in relation to them too. I can't check either way at the moment however as I'm not on my dev machine.
Can you confirm to contrary?
10/25/2010 (11:29 pm)
I'm on SDK4 and iTGB 1.4 and not getting this problem as far as I'm aware... so I'm of the thinking that it is something in your code that is going awry.@Scott: For some reason I had it in my head that when you delete datablocks that have nothing referencing them that will also cleanup the memory related to the graphics (ie imagemap) in relation to them too. I can't check either way at the moment however as I'm not on my dev machine.
Can you confirm to contrary?
#11
10/26/2010 (8:38 am)
Craig, you are probably right, however, whenever I delete a datablock the image still seems to hang around and this is confirmed when I delete the image map because I get the nag message about existing reference counts. For the life of me I can't see where these other references are.
#12
10/26/2010 (3:18 pm)
Craig & Scott - So the way we have it coded should work then and be removing the graphic object from memory? But of course it isn't. :)
#13
Are you 100% sure you are leaking graphics memory? I can take a look at this for you but obviously I would need access to your source (I won't be offended if you say no lol)
10/26/2010 (3:28 pm)
Well you are deleting objects, not datablocks - so the resources allocated by said datablocks (the images) are still hanging around. BUT in the lifetime of a level that shouldn't be a problem anyway... (you'd only want to zap them at the end of a level)Are you 100% sure you are leaking graphics memory? I can take a look at this for you but obviously I would need access to your source (I won't be offended if you say no lol)
#14
Each runner is adding ~100KB to live memory and we run out 1-10 per wave, and there are 100 waves per level, so it does add up to a significant, crashable amount.
10/26/2010 (4:08 pm)
Craig - that helps. I'll talk with our programmer today. Each runner is adding ~100KB to live memory and we run out 1-10 per wave, and there are 100 waves per level, so it does add up to a significant, crashable amount.
#15
I'll try to describe the problem more deep:
1). Datablocks of runners are loading at start of the level and releasing at the end of the level, so we're not speaking about datablocks
2). We made simple test:
animated sprite created, on schedule deleted...
the test was with thousands of runners appearing/deleting
no metter to use safeDelete or delete - with time leaks appearing like few KB per minute.
nothing else loading/deleting/changing in the game at this moment, just animated sprites creating/deleting
10/26/2010 (4:24 pm)
Hi all!I'll try to describe the problem more deep:
1). Datablocks of runners are loading at start of the level and releasing at the end of the level, so we're not speaking about datablocks
2). We made simple test:
animated sprite created, on schedule deleted...
the test was with thousands of runners appearing/deleting
no metter to use safeDelete or delete - with time leaks appearing like few KB per minute.
nothing else loading/deleting/changing in the game at this moment, just animated sprites creating/deleting
#16
1) We load in the runners at the beginning of a level. That loads into a datablock. There are 5 runners. Each one takes ~800KB (they are animated, fairly detailed)
2) As each wave starts we create objects that are "instances" of those runners. A wave may have 3 of runner type 1, for example.
3) When those runners reach their goal or are defeated we delete that "instance". However, the memory bump that occurred when they were created (~100KB) does not go away. It accumulates wave after wave.
Is there a way to free up the memory from that "instance" creation?
And, if it helps I will send you the game source. I have seen you on these boards enough to know you're a solid member of the community. :)
My email is djzeaman at gmail dot com.
10/26/2010 (4:45 pm)
Craig - I spoke with our programmer, I think I understand it a little better now.1) We load in the runners at the beginning of a level. That loads into a datablock. There are 5 runners. Each one takes ~800KB (they are animated, fairly detailed)
2) As each wave starts we create objects that are "instances" of those runners. A wave may have 3 of runner type 1, for example.
3) When those runners reach their goal or are defeated we delete that "instance". However, the memory bump that occurred when they were created (~100KB) does not go away. It accumulates wave after wave.
Is there a way to free up the memory from that "instance" creation?
And, if it helps I will send you the game source. I have seen you on these boards enough to know you're a solid member of the community. :)
My email is djzeaman at gmail dot com.
#17
We seem to have gone down the route that it is memory that was allocated for graphics that is being leaked, can I just ask why? I haven't seen anything that seems to specifically point in this direction short of the fact that they are animated sprite objects... (which does infer that in likelihood it is graphics memory but doesn't confirm it)
Email sent
10/26/2010 (4:52 pm)
I'm assuming Vyacheslav is your programmer :)We seem to have gone down the route that it is memory that was allocated for graphics that is being leaked, can I just ask why? I haven't seen anything that seems to specifically point in this direction short of the fact that they are animated sprite objects... (which does infer that in likelihood it is graphics memory but doesn't confirm it)
Email sent
#18
The premise is simple:
- get an animated sprite from the pool e.g. runner
- show it on screen
- on death, world limit etc, put runner back into the pool and set to disabled
- repeat
You never delete the object unless it is not needed on certain levels, and then you can delete all objects of that type in the pool.
HTH
10/26/2010 (7:42 pm)
Django, I think the reason most of us don't see the problem is because we all used animated and static sprite pools e.g. over the course of a game I will have created 100's of missiles and bombs but I reuse objects in the pool and therefore don't see the leaks.The premise is simple:
- get an animated sprite from the pool e.g. runner
- show it on screen
- on death, world limit etc, put runner back into the pool and set to disabled
- repeat
You never delete the object unless it is not needed on certain levels, and then you can delete all objects of that type in the pool.
HTH
#19
Yes, Slava is our programmer.
The reason why we think it is graphic memory is that live memory and leaked bytes go up as the number of runners entering the scene goes up.
When no runners enter then live bytes and leaked bytes stay constant.
Also the amount the live bytes and leaked bytes go up is proportional to the number of runners entering the scene.
1 runner - ~100 KB added to live bytes and 60-70 KB added to leaked bytes
10 runners - ~1,000 KB added to lives bytes and 600-700 KB added to leaked bytes.
So from the memory leak instruments readings it appears to be limited to that specifically. We have tried stripping out all the pathfinding and even the animation and just displaying a still runner graphic and deleting it and we still get the proportional rise in live bytes and leaked bytes, so it seems like something basic is not releasing from memory. Or we don't know how to properly clean that memory chunk.
10/26/2010 (8:21 pm)
Craig,Yes, Slava is our programmer.
The reason why we think it is graphic memory is that live memory and leaked bytes go up as the number of runners entering the scene goes up.
When no runners enter then live bytes and leaked bytes stay constant.
Also the amount the live bytes and leaked bytes go up is proportional to the number of runners entering the scene.
1 runner - ~100 KB added to live bytes and 60-70 KB added to leaked bytes
10 runners - ~1,000 KB added to lives bytes and 600-700 KB added to leaked bytes.
So from the memory leak instruments readings it appears to be limited to that specifically. We have tried stripping out all the pathfinding and even the animation and just displaying a still runner graphic and deleting it and we still get the proportional rise in live bytes and leaked bytes, so it seems like something basic is not releasing from memory. Or we don't know how to properly clean that memory chunk.
#20
I think I understand. So if we know that runner type #1 will only appear on screen a maximum of 5 times at any one time, then we create a pool of 5 of those runner graphics and display from that pool.
Slava is going to try a build on that principle now. Thank you!
10/26/2010 (8:23 pm)
Scott,I think I understand. So if we know that runner type #1 will only appear on screen a maximum of 5 times at any one time, then we create a pool of 5 of those runner graphics and display from that pool.
Slava is going to try a build on that principle now. Thank you!
Torque Owner Johnny Vo