Just wondering as I develop my game (and learn Lua / Corona), is there a tool to check that I’m not leaking memory. For example if I load a sound effect in the game ‘screen’ when I return to the menu ‘screen’ will it be unloaded automatically? [import]uid: 9371 topic_id: 3790 reply_id: 303790[/import]
As for sounds, currently not. Ansca says we’ll be able to free sounds in the next release.
So, for now, keep in mind that all sounds will stay there, AFAIK.
As for display objects, you might want to print out the number of children in stage, whenever you “change page”. If the number grows at each page change you know you’re not freeing stuff. [import]uid: 5750 topic_id: 3790 reply_id: 11514[/import]
Forgive me, “print out the number of children”, erm uh? How!? [import]uid: 9371 topic_id: 3790 reply_id: 11518[/import]
Just to outline the methods and members…
[lua]local curstage = display.getCurrentStage()
print(curstage.numChildren)[/lua]
Consider there is only one stage at the moment… so you might want to get it just at startup. [import]uid: 5750 topic_id: 3790 reply_id: 11519[/import]
Do I have to free listeners? [import]uid: 9371 topic_id: 3790 reply_id: 11523[/import]
Well, you should remove them… yes, if you add them every time you enter a “page”.
Not really because of memory, but because you might refer to a “bad self” inside a listener if you keep adding without removing. [import]uid: 5750 topic_id: 3790 reply_id: 11525[/import]
Sorry but how do I remove them? [import]uid: 9371 topic_id: 3790 reply_id: 11527[/import]
removeListener. the same as what you used to add them. just change the addListener to removeListener and keep the rest of the code the same [import]uid: 6645 topic_id: 3790 reply_id: 11530[/import]
And what about other memory leaks caused by not nil objects?
[import]uid: 9371 topic_id: 3790 reply_id: 11699[/import]
When I leave my game ‘screen’ I do this:
local curstage = display.getCurrentStage()
print("Number of children = "…curstage.numChildren)
It reports 6.
If I then go back into the game ‘screen’ and exit again it reports 12
So it would appear that I’m not releasing something. All my variables are local.
HELP! [import]uid: 9371 topic_id: 3790 reply_id: 11709[/import]
Would this cause a leak?
local grass = display.newImage(“images/grass.png”)
grass.y = display.contentHeight -
layer_back:insert(grass)
Without explicitly doing
grass=nil
at the end? [import]uid: 9371 topic_id: 3790 reply_id: 11710[/import]
From your results it looks like they’re not collected *immediately*.
It might get collected *at some point*, which is probably not what you need.
This might get a bit complicated if explained “in full”. One thing you can do is to use the object:removeSelf() method available from Corona. (instead of nilling the object)
This will collect the object immediately whatever reference it might have within the whole code.
Surely, you will get errors if any other piece of code will try to access the object once you removed it.
If this is good in your case, stick with it.
Also, read whatever you can regarding Lua garbage collection system in the Lua official user guide. It will give you a better understanding of how it works and how to adapt it to your needs.
One thing I usually do in my code is to devote some frames to garbage collection steps at runtime, to ensure local variables are collected regularly.
Example code to execute within an enterFrame event (i.e. every frame):
[lua]game = {
gc={20,10,0}, – [1] every Nth. frame [2] collection steps [3] frame count
rate = 59 – actual frame rate, minus 1
}
– since gc[1] == 20, it will perform 10 GC steps 3 times per second at 60 fps.
local function doGC()
local f = game.gc[3]%game.gc[1] – gives the remainder of the division
if f == 0 then – if remainder is 0 then it’s time to collect
collectgarbage(“step”,game.gc[2]) – runs N. cycles of GC
end
game.gc[3] = game.gc[3]+1 – runs the frame counter
if game.gc[3] > gc.rate then – resets counter
game.gc[3] = 0 – this ensures it collects at least gc[2] steps every second
end
end
Runtime:addEventListener(“enterFrame”, doGC) – starts it all[/lua]
This is a way to distribute GC in time, rather than force a full collection cycle at any *single* frame. If you issue a collectgarbage() command in a single frame, since the operation will require a considerable amount of CPU cycles, you will have a very “slowly” rendered frame, likely resulting in visible “hiccups” in graphics and animations. (depending on how much garbage you leave around) [import]uid: 5750 topic_id: 3790 reply_id: 11727[/import]
So in my case would
layer_back:removeSelf()
remove the layer_back object and any ‘children’ like the grass variable?
In none of the Corona examples have I seen any explicit garbage collection or clean up routines. Perhaps it would be nice if Ansca would create an example or even better an official director. [import]uid: 9371 topic_id: 3790 reply_id: 11744[/import]
It’s not uncommon not to include GC management code within “examples”. While Game apps are intensive applications, a single example rarely needs such “touches”. This is entirely up to the single developer.
Lua GC works as expected with most uses… that is, at some point will release resources - unless they’re referenced somewhere. But, as said, sometimes this is not enough.
Actually, Ansca got a page discussing memory management:
Hope it helps.
EDIT: if I recall though, they changed the removeSelf() behavior lately. That is, it will collect immediately regardless of the references - but I’m not 100% sure, since, AFAIK, the docs need to be updated.
EDIT2: Here it is:
http://developer.anscamobile.com/content/memory-management-changes-corona-sdk-beta-8 [import]uid: 5750 topic_id: 3790 reply_id: 11747[/import]
Sorry it’s still not clear.
So in my case would
layer_back:removeSelf()
remove the layer_back object and any ‘children’ like the grass variable?
or should I do
grass:removeSelf()
layer_back:removeSelf() [import]uid: 9371 topic_id: 3790 reply_id: 11748[/import]
I’d suggest removing children first, of course. Otherwise you risk to leave those children allocated “in the wild”.
Lua docs refer to those as “unreachables”.
(unless Ansca’s removeSelf() already provides this functionality… but it’s not specified currently, so, for now, I must assume it’s not)
Further reading:
http://lua-users.org/wiki/GarbageCollectionTutorial [import]uid: 5750 topic_id: 3790 reply_id: 11749[/import]