On which situations should I set a variable to nil to free memory?

Hi there,

When you are developing an app for mobile, one of your concerns, is to conserve memory allocation. When you are creating a variable, you should always set it free, since you don’t use it anymore, so the garbage collector works as expected.

Should this be done for each variable? Like, even variables inside tables?

Example:

[lua]

local a = 1

local b = ‘asd’

local c = {

    foo = function () end,

    [1]  = ‘…’,

    tab = {

        boo = 123,

    }

}

[/lua]

In the code above, the variables a, b and c should be freed from memory right? Should the same happen with: c.foo, c[1], c.tab.boo and c.tab?

Thanks,

Carlos HR.

Lua’s garbage collector will automatically free a variable when it is no longer referenced.  One of the ways that happens is simply when the variable goes out of scope, like local variables of a block or function.  Another way that happens is when you explicitly set all references to nil.  Setting a table to nil will release the entire table - you need not individually nil out each key first.  As to specifically when to explicitly nil out a variable:  whenever it is no longer needed.

For Corona, the thing that trips up many is the difference between display objects and references to them.  Lua itself does not (by default) know anything about those “special” references, so may require special handling, eg:

t = {} t.rect = display.newRect(10,10,10,10) t = nil -- t is destroyed, t's reference to display object is destroyed -- BUT!!! display object STILL exists in display, and is orphaned (no ref to it)!! potential leak

instead:

t = {} t.rect = display.newRect(10,10,10,10) display.remove(t.rect) t = nil -- now everything (table, reference and object) are properly disposed of

There are techniques that can (potentially) give the illusion of simpler cleanup, but (IMO) best practice with display objects is:  if you explicitly created it, then you should explicitly destroy it.

Hi Dave, Thanks for the reply.

After seeing this information countless times in the Corona’s API Reference, I already understand how it works with display objects. What I still don’t understand, and I guess I didn’t make it clear… sorry, my fault… was something like this with the Lua tables:

I have a table:

[lua]

local t = {}

[/lua]

Now, I add something inside the table. I inserted a function, but it could be any other type of data: bool, number, string, table, userdata:

[lua]

t.add = function (a, b) return a+b end

[/lua]

So, at this moment I will free the table from memory.

Questions that come into my mind:

  1. Do I need to set t.add as nil, so the garbage collector removes the table from memory?
  2. Does t.add still gets allocated if the table reference is set to nil?

[lua]

if (‘Should I have to do this?’) then

    t = nil

elseif (‘Or I must remove all fields inside the table first?’) then

    t.add = nil

    t = nil

end

[/lua]

Also, should I really need to remove sequential fields [1], [2], …, [n], if I want to free all data?

Thanks,

Carlos HR.

As long as nothing else Is referencing t.add, or any of its other children, the memory will be released just by setting t to nil.

[lua]

local t = { myScore = 50 }

– somewhere later in the program…

local score = t.myScore

– even later…

t = nil     – myScore will still be in memory as score is referencing it.

[/lua]

Hi Nick, thanks for the reply.

I see… it makes sense I guess… thank you! That really solves my question.

Lua’s garbage collector will automatically free a variable when it is no longer referenced.  One of the ways that happens is simply when the variable goes out of scope, like local variables of a block or function.  Another way that happens is when you explicitly set all references to nil.  Setting a table to nil will release the entire table - you need not individually nil out each key first.  As to specifically when to explicitly nil out a variable:  whenever it is no longer needed.

For Corona, the thing that trips up many is the difference between display objects and references to them.  Lua itself does not (by default) know anything about those “special” references, so may require special handling, eg:

t = {} t.rect = display.newRect(10,10,10,10) t = nil -- t is destroyed, t's reference to display object is destroyed -- BUT!!! display object STILL exists in display, and is orphaned (no ref to it)!! potential leak

instead:

t = {} t.rect = display.newRect(10,10,10,10) display.remove(t.rect) t = nil -- now everything (table, reference and object) are properly disposed of

There are techniques that can (potentially) give the illusion of simpler cleanup, but (IMO) best practice with display objects is:  if you explicitly created it, then you should explicitly destroy it.

Hi Dave, Thanks for the reply.

After seeing this information countless times in the Corona’s API Reference, I already understand how it works with display objects. What I still don’t understand, and I guess I didn’t make it clear… sorry, my fault… was something like this with the Lua tables:

I have a table:

[lua]

local t = {}

[/lua]

Now, I add something inside the table. I inserted a function, but it could be any other type of data: bool, number, string, table, userdata:

[lua]

t.add = function (a, b) return a+b end

[/lua]

So, at this moment I will free the table from memory.

Questions that come into my mind:

  1. Do I need to set t.add as nil, so the garbage collector removes the table from memory?
  2. Does t.add still gets allocated if the table reference is set to nil?

[lua]

if (‘Should I have to do this?’) then

    t = nil

elseif (‘Or I must remove all fields inside the table first?’) then

    t.add = nil

    t = nil

end

[/lua]

Also, should I really need to remove sequential fields [1], [2], …, [n], if I want to free all data?

Thanks,

Carlos HR.

As long as nothing else Is referencing t.add, or any of its other children, the memory will be released just by setting t to nil.

[lua]

local t = { myScore = 50 }

– somewhere later in the program…

local score = t.myScore

– even later…

t = nil     – myScore will still be in memory as score is referencing it.

[/lua]

Hi Nick, thanks for the reply.

I see… it makes sense I guess… thank you! That really solves my question.