Memory Leak Problem

I have a game that basically generates several (10 or more) display.newSprite() objects every 2-4 seconds… then it does that 10 or more times. (the sprites are spider sprites)

Each spider sprite starts at or below the bottom of the screen and move up towards the top. The player has to “touch” each spider as it moves up the screen, or the player misses it.

Each time a spider is added, I add it to a table I’ve created called spiders. I add it kinda like this:
[lua]local spider = spidersobject.newSpider(type)
spider:play()
spiders[i] = spider
localGroup:insert( spiders[i] )[/lua]

Now, if the spider is “missed” or “touched”, I try to kill the object kinda like this:
[lua] local function killspider(i, escaped)
print(’\n\n=============\nremoving spider '… i)

local spider_type = spiders[i].type

spiders[i].halt = true
spiders[i].escaped = escaped
spiders[i].type = spider_type
spiders[i].doremove = false
spiders[i].isremoved = true

spiders[i]:removeEventListener(“touch”, touchspider)
spiders[i]:removeSelf()

print(’--------Debug---------’)
for k,v in pairs(spiders[i]) do
print(k,v)
end

end[/lua]
HOWEVER, every few seconds I print out my memory usage and it goes up and up and up (over 1200 sometimes), and never comes down. ALSO, you’ll notice in my code above where I print Debug, that shows this, which to me seems like it doesn’t actually remove the event listener…

direction 1  
score 34  
halt true  
isremoved true  
doremove false  
speedx 3  
\_class table: 0x5639630  
\_functionListeners table: 0x22c4270  
hasevent true  
speed 93  
escaped true  
type 5  
\_proxy userdata: 0x2263614  
alpha 1  

Any help, guys? Am I removing sprites the wrong way? Is having all these sprites in a table screwing me up?

Thanks,
David [import]uid: 60144 topic_id: 24466 reply_id: 324466[/import]

Try also setting the spider to nil after removeSelf()

spiders[i] = nil [import]uid: 14018 topic_id: 24466 reply_id: 99007[/import]

In addition to what Mitaten added, add the following below his line.

collectgarbage("collect") [import]uid: 56820 topic_id: 24466 reply_id: 99009[/import]

Thanks guys. That seems to have helped.

The reason I didn’t set it to nil was because I still needed its values, so I did this:

[lua] local function killspider(i, escaped)
print(’\n\n=============\nremoving spider '… i)

local spider_type = spiders[i].type

spiders[i]:removeEventListener(“touch”, touchspider)
spiders[i]:removeSelf()
spiders[i] = nil
collectgarbage(“collect”)

spiders[i] = {}
spiders[i].halt = true
spiders[i].escaped = escaped
spiders[i].type = spider_type
spiders[i].doremove = false
spiders[i].isremoved = true
spiders[i].hasevent = true

print(’-----------------’)
for k,v in pairs(spiders[i]) do
print(k,v)
end

end[/lua]
Unfortunately, even though I can see my memory going down - I use collectgarbage(“count”) - it’s not returning to the start value I had at the beginning of the level. =(
[import]uid: 60144 topic_id: 24466 reply_id: 99014[/import]

Oh shoot, nevermind, it didn’t work completely… =(

The memory usage is going down, but not all the way. Something is still inflating the memory. [import]uid: 60144 topic_id: 24466 reply_id: 99015[/import]

Just an FYI, you can’t really, remove the listener, nil the object, collectgarbage and then reuse it right away. It does not have time to clear the memory before your re-assigning it data.

One way to handle this (not sure it’s the best) would be to delay the re-assigning of your spider.

Something like so. Make a spider creation function.

function CreateSpider(i, esc, t)  
 spiders[i] = {}  
 spiders[i].halt = true   
 spiders[i].escaped = esc  
 spiders[i].type = t  
 spiders[i].doremove = false  
 spiders[i].isremoved = true   
 spiders[i].hasevent = true  
end  

Then in your killspider function where you are now re-assigning all the data, just execute the CreateSpider function but on a delay. Give the engine time to clear some memory. It doesnt have to be a long delay though. So we pass the variables you want to this new CreateSpider function.

local function killspider(i, escaped)  
 print('\n\n=============\nremoving spider '.. i)  
  
 local spider\_type = spiders[i].type  
   
 spiders[i]:removeEventListener("touch", touchspider)  
 spiders[i]:removeSelf()  
 spiders[i] = nil  
 collectgarbage("collect")  
   
 timer.performWithDelay(10, function() CreateSpider(i, escaped, spider\_type) end)  
   
 print('-----------------')  
 for k,v in pairs(spiders[i]) do  
 print(k,v)  
 end  
   
 end  

I am not sure the specifics of your code outside this function. However if you are clearing spiders, than re-using them by adding data back in, your memory can’t really ever be completely empty. As long as the lowest memory value doesn’t keep creeping higher and higher, it should be ok. [import]uid: 56820 topic_id: 24466 reply_id: 99023[/import]

As an update: I’ve fixed the memory leak problem by using table.remove(tablename, index)

But there’s a new problem now.

Sometimes it seems like my transitions are not completing. I think I may be overloading the system with sprites… There can be hundreds on the screen at once, potentially. But I think I can even account for any possible glitches.

For now, I’m declaring this problem solved.

Thanks again, I’ll just create a new ticket if there’s a new problem.

David [import]uid: 60144 topic_id: 24466 reply_id: 99125[/import]