spawn same display object and memory management

Hi,

I spawn objects and clean up as below but there seem to be memory leak.

  
local function spawnBomb()  
 local bomb = display.newImage("bomb.png")  
 bombs[bomb] = bomb  
 bombs[bomb].x = math.random(\_W/2, \_W/2)  
 bombs[bomb].name = "bomb"  
 physics.addBody(bombs[bomb], {bounce=0})  
 bombs[bomb].bodyType = "kinematic"  
 bombs[bomb].isSensor = true  
 bombs[bomb].y = math.random(-100, -10)  
 bombGroup:insert(bombs[bomb])  
 bombs[bomb]:setLinearVelocity(0, math.random(100, 110))  
 function onCollision(e)  
 if e.phase == "began" then  
 bombs[bomb]:removeSelf()  
 bombs[bomb] = nil  
 end  
 end  
 bombs[bomb]:addEventListener("collision", onCollision)  
end  
tmrSpawnBomb = timer.performWithDelay(200, spawnBomb, 0)  
local function cleanUp()  
  
 if bombGroup.numChildren then  
 for i=bombGroup.numChildren, 1, -1 do  
 if bombGroup[i].y \> 150 then  
 bombGroup[i]:removeEventListener("collision", onCollision)  
 bombGroup[i]:removeSelf()  
  
 end  
 end  
 end  
end  
tmrCheckBubble = timer.performWithDelay(20, cleanUp, 0)  

Is there any problem spawning object this way? I spawn a few other objects this way too and print(collectgarbage(“count”)) show the number keep increasing. It reach 2500 (2.5MB?) in 10 minutes, is this increasing rate memory leak? Thanks.

Steve

[import]uid: 84159 topic_id: 14805 reply_id: 314805[/import]

I think the cleanUp function only remove the display object, but the table structure of the object is there unless we set the object to nil, thus causing the memory leak.

bombGroup[i] = nil will generate WARNING: Attempting to set property(1) with nil.

How to set object to nil with such cleapUp function or any other function? Is there a better way to spawn objects with the same file name and object name and clean it up after its Y or X exceed certain point?

Steve
[import]uid: 84159 topic_id: 14805 reply_id: 54806[/import]

This part here;

[lua]function onCollision(e)
if e.phase == “began” then
bombs[bomb]:removeSelf()
bombs[bomb] = nil
end
end[/lua]

Is a little off - you shouldn’t be trying to remove an object until AFTER collision has resolved. This could be causing some issues. [import]uid: 52491 topic_id: 14805 reply_id: 54844[/import]

Thanks, Peach Pellen. Thought I don’t have the delay, it doesn’t make any error at the moment but to be safe I’ll add delay timer. How about cleanUp function? Does it make sense?

Steve [import]uid: 84159 topic_id: 14805 reply_id: 54854[/import]

Hi. This is how you should be doing your spawns…

[code]

local function spawnBomb()
local bomb = display.newImage(“bomb.png”)
bomb.x = math.random(_W/2, _W/2)
bomb.name = “bomb”
physics.addBody(bomb, {bounce=0})
bomb.bodyType = “kinematic”
bomb.isSensor = true
bomb.y = math.random(-100, -10)
bomb.index = #bombs + 1
bombGroup:insert(bomb)

bomb:setLinearVelocity(0, math.random(100, 110))
function onCollision(e)
if e.phase == “began” then
bomb:removeSelf()
bomb = nil
end
end
bomb:addEventListener(“collision”, onCollision)

bombs[bomb.index] = bomb

return bomb

end
[/code] [import]uid: 84637 topic_id: 14805 reply_id: 54934[/import]

@Danny, how can I remove bomb when it goes off screen? I can do it by setting up an off screen object to collide with bomb, but is there any other ways? Thank you.

Steve [import]uid: 84159 topic_id: 14805 reply_id: 54995[/import]

The way you suggested is probably the best way.

However you can also remove them this way (in a for loop, in a runtime listener)

  
for i, v in pairs(bombs) do  
 --if bomb leaves right side of screen  
 if bombs[i].x + bombs[i].width / 2 \> display.contentWidth then  
 bombs[i]:removeSelf()  
 table.remove(bombs, i)  
 bombs[i] = nil  
 end  
end  

[import]uid: 84637 topic_id: 14805 reply_id: 55056[/import]

@Danny, it removes the object if there is only one passing the threshold line, but if there are more, some are not removed. I put together the code below for your review just in case I’ve done something wrong.

\_W = display.contentWidth  
\_H = display.contentHeight  
local physics = require("physics")  
physics.start()  
local bombs = {}  
local bombGroup = display.newGroup()  
  
local function spawnBomb()  
 local bomb = display.newImage("bomb.png")  
 bomb.x = math.random(0, \_W)  
 bomb.name = "bomb"  
 physics.addBody(bomb, {bounce=0, filter=b})  
 bomb.bodyType = "kinematic"  
 bomb.isSensor = true  
 bomb.y = math.random(-100, -10)  
 bomb.index = #bombs + 1  
 bombGroup:insert(bomb)  
 bomb:setLinearVelocity(0, math.random(100, 110))  
 function onCollision(e)  
 if e.phase == "began" then  
 bomb:removeSelf()  
 bomb = nil  
 end  
 end  
 bomb:addEventListener("collision", onCollision)  
   
 bombs[bomb.index] = bomb  
   
 return bomb  
   
end  
tmrSpawnBomb = timer.performWithDelay(1000, spawnBomb, 0)  
local function removeBomb()  
for i, v in pairs(bombs) do  
 if bombs[i].y \>100 then  
 bombs[i]:removeSelf()  
 table.remove(bombs, i)  
 bombs[i] = nil  
 end  
end  
end  
Runtime:addEventListener("enterFrame", removeBomb)  

Steve [import]uid: 84159 topic_id: 14805 reply_id: 55065[/import]

@Danny, I think I found what cause the problem. We only need to use either table.remove(bombs, i) or bombs[i] = nil.

So the removeBall function should be like this

local function removeBomb()  
 for i, v in pairs(bombs) do  
 if bombs[i].y \>100 then  
 bombs[i]:removeSelf()  
 bombs[i] = nil  
 end  
 end  
end  

or

local function removeBomb()  
 for i, v in pairs(bombs) do  
 if bombs[i].y \>100 then  
 bombs[i]:removeSelf()  
 table.remove(bombs, i)  
 end  
 end  
end  

Steve
[import]uid: 84159 topic_id: 14805 reply_id: 56809[/import]

Hi,

When you remove bombs, you don’t seem to care about remove eventlisteners attached to them.

Is it just because removeSelf() does it for you ?

Thx [import]uid: 9328 topic_id: 14805 reply_id: 63569[/import]

Antheor, that’s correct :slight_smile: (If you look at the sample code available you will notice event listeners aren’t manually removed when removeSelf() is used.)

Peach :slight_smile: [import]uid: 52491 topic_id: 14805 reply_id: 63703[/import]

Thx Peach :slight_smile: [import]uid: 9328 topic_id: 14805 reply_id: 63747[/import]

I have the following question :
I have to do :

for i=1,#lines do  
display.remove(lines[i])-- remove from screen  
lines[i]:removeSelf()-- brings an error (already removed)  
lines[i] = nil  
end  

The problem is that lines[i]:removeSelf() does not remove my line from screen, so the question :slight_smile:
Is display.remove(lines[i]) enough for a proper removal (with listeners attached …) ?
[import]uid: 9328 topic_id: 14805 reply_id: 65428[/import]

Yep, it’s enough according to Jon’s post here:

http://blog.anscamobile.com/2011/08/corona-sdk-memory-leak-prevention-101/

In particular, the part where he does

display.remove( redBall )  
redBall = nil  

Once you remove your line of code:

lines[i]:removeSelf()-- brings an error (already removed)  

you should be good to go. [import]uid: 11636 topic_id: 14805 reply_id: 65468[/import]

Thx for your help.
I don’t know why, but I’m always anxious when it comes to the remove thing…:slight_smile: [import]uid: 9328 topic_id: 14805 reply_id: 65473[/import]

No problem, I’m the same way too! That’s why I was glad to once-and-for-all get that blog entry from Jon and now I stick to it! :slight_smile:

-Mario [import]uid: 11636 topic_id: 14805 reply_id: 65563[/import]

Hey there I have been following links and links and stumbled across your method of spawning in objects danny, as it appears you have also provided means for removing/destroying the objects however when trying to implement what has been said here to what I’ve interpreted has provided countless errors.

The way in which my deletions work is picture a playable object, with movement of a joystick deletes the spawned civilians.
For each deleted civilian I run the spawner to create a further 2 more civilians to the screen so an exponential growth.

the collision detection I’ve set up is fine but with your line here from your spawning objects the right way tutorial:

peeps.objTable[peeps.index] = peeps

it isn’t happy

any help would be muchily appreciated :slight_smile:
[import]uid: 87730 topic_id: 14805 reply_id: 143733[/import]

Hey there I have been following links and links and stumbled across your method of spawning in objects danny, as it appears you have also provided means for removing/destroying the objects however when trying to implement what has been said here to what I’ve interpreted has provided countless errors.

The way in which my deletions work is picture a playable object, with movement of a joystick deletes the spawned civilians.
For each deleted civilian I run the spawner to create a further 2 more civilians to the screen so an exponential growth.

the collision detection I’ve set up is fine but with your line here from your spawning objects the right way tutorial:

peeps.objTable[peeps.index] = peeps

it isn’t happy

any help would be muchily appreciated :slight_smile:
[import]uid: 87730 topic_id: 14805 reply_id: 143733[/import]

Hey there I have been following links and links and stumbled across your method of spawning in objects danny, as it appears you have also provided means for removing/destroying the objects however when trying to implement what has been said here to what I’ve interpreted has provided countless errors.

The way in which my deletions work is picture a playable object, with movement of a joystick deletes the spawned civilians.
For each deleted civilian I run the spawner to create a further 2 more civilians to the screen so an exponential growth.

the collision detection I’ve set up is fine but with your line here from your spawning objects the right way tutorial:

peeps.objTable[peeps.index] = peeps

it isn’t happy

any help would be muchily appreciated :slight_smile:
[import]uid: 87730 topic_id: 14805 reply_id: 143733[/import]

Hey there I have been following links and links and stumbled across your method of spawning in objects danny, as it appears you have also provided means for removing/destroying the objects however when trying to implement what has been said here to what I’ve interpreted has provided countless errors.

The way in which my deletions work is picture a playable object, with movement of a joystick deletes the spawned civilians.
For each deleted civilian I run the spawner to create a further 2 more civilians to the screen so an exponential growth.

the collision detection I’ve set up is fine but with your line here from your spawning objects the right way tutorial:

peeps.objTable[peeps.index] = peeps

it isn’t happy

any help would be muchily appreciated :slight_smile:
[import]uid: 87730 topic_id: 14805 reply_id: 143733[/import]