How are tables cleared the right way?

@d.mach - You’re making this more complicated that it is.

  1. If there is variable (*anywhere*) that references a display object and you delete that display object, it WILL NOT be garbage collected.

  2. You can delete objects in three ways:

  • Delete them directly with display.remove( obj ) 
  • Delete them directly with obj:removeSelf( ) – I do not use this because it is unsafe.  Just one mistake can bite you.
  • Delete them by deleting the group they are a child of.
  1. Deleting objects does nothing to variables that reference the objects.

  2. When you have fields on a table or object and that object goes out of scope, the fields are cleared.  i.e. If they were referencing an object, that reference is now gone.

  3. You can clear a variable reference (to a table of a object) to fall out of scope immediately by setting the variable that references the table or object to nil.

    local obj1 = display.newCircle( … ) local obj2 = display.newCircle( … ) local t1 = {} obj1.circ = obj2 t1.circ = obj2 – At this point, both obj1 and t1 have fields referencing obj2 display.remove(obj1) display.remove(obj2) – At this point obj1 and obj2 are removed obj1 = nil obj2 = nil – At this point obj1 can be garbage collected but not obj2 t1 = nil – At this point obj1 and obj2 can be garbage collected

Thanks for the detailed info. This is exactly what I was looking for and which was not clear before!

While searching for a system memory leak I found the following problem with my code:

I’m using a global function with a global transitionStash I always clear with a scene change:

transitionStash={} function cancelAllTransitions()     local x          for x=#transitionStash,1,-1 do         transition.cancel( transitionStash[x])         --print ("Transition Nr. ",x," deleted now!")         transitionStash[x]=nil     end     transitionStash = nil     transitionStash = {}     performWithDelay (1,function() collectgarbage("collect") end,1)     return true end

I’m using this for example inside a mainmenu scene, when clicking on a button some transitions will blend in a level selection overview inside the mainmenu. A back-button will then (also with transitions) blend out the level selection and show the original button again.

After clicking the button again the level selection overview is shown again (using transitions) and the back-button will blend the overview out again… and so on.

After doing this for about 20 times, the system memory will increase about 1MB and tests have shown it is the growing transitionStash array.

Now I wonder how I can use a transitionStash AND avoid the growing system memory?

Here is the code (function) which is called when the back-button is used to show the original main buttons again after the level selection buttons where shown:

local showmenuimagesagain = function()             --blending in all the images we need for the main menu:             transitionStash[#transitionStash+1]=transition.to(gfx.titlelogoshadow,{time=250,delay=1,alpha=0.08,tag="newstart",transition=easing.outQuad})             transitionStash[#transitionStash+1]=transition.to(gfx.titlelogo,{time=320,delay=10,alpha=1,tag="newstart",transition=easing.outQuad})             transitionStash[#transitionStash+1]=transition.to(gfx.btn\_newstart,{time=320,delay=50,alpha=1,tag="newstart",transition=easing.outQuad})             transitionStash[#transitionStash+1]=transition.to(gfx.playbtn\_txt,{time=300,delay=40,alpha=1,tag="newstart",transition=easing.outQuad})             transitionStash[#transitionStash+1]=transition.to(gfx.playbtn\_txtshadow,{time=300,delay=30,alpha=0.25,tag="newstart",transition=easing.outQuad})             transitionStash[#transitionStash+1]=transition.to(gfx.btn\_newrate,{time=320,delay=70,alpha=1,tag="newstart",transition=easing.outQuad})             transitionStash[#transitionStash+1]=transition.to(gfx.ratebtn\_txt,{time=300,delay=60,alpha=1,tag="newstart",transition=easing.outQuad})             transitionStash[#transitionStash+1]=transition.to(gfx.ratebtn\_txtshadow,{time=300,delay=51,alpha=0.25,tag="newstart",transition=easing.outQuad})             fc.startinfotextanimation()             transitionStash[#transitionStash+1]=transition.to(gfx.settings,{time=320,delay=80,alpha=1,transition=easing.inQuad,onComplete=function() composer.state.buttonsactive=1;transition.resume("newstart") end})             transitionStash[#transitionStash+1]=transition.to(gfx.btn\_languageselection,{time=300,delay=60,alpha=1,transition=easing.inQuad})             transitionStash[#transitionStash+1]=transition.to(gfx.btn\_difficulty,{time=300,delay=60,alpha=1,transition=easing.inQuad})             transitionStash[#transitionStash+1]=transition.to(gfx.difficultyicon,{time=300,delay=60,alpha=1,transition=easing.inQuad})             transitionStash[#transitionStash+1]=transition.to(gfx.flagimg,{time=300,delay=60,alpha=1,transition=easing.inQuad})              end

Calling cancelAllTransition() at scene change will clear the used memory btw.