4

Let us see the following codes.

do
    local a = {1,2,3}
    function a:doSth()
        self = nil
    end

    a:doSth()

    if a then
        print("Still has a...")
    end
end

I found that this method doesn't work. The table a still exists. Why? I know the a = nil can reclaim the memory which table a holds. How to directly get the memory holds by the table a and free the memory just like delete in C++?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
NiklausTseng
  • 235
  • 2
  • 10

2 Answers2

4
function a:doSth()
    self = nil
end

Is syntax sugar for

function a.doSth(self)
    self = nil
end

Your above code, there are two different references to the table value {1,2,3}, one is through local a, the other is through self inside the function. niling out one of the references doesn't change the other reference to the table.

For that table to be considered for gc collection, you have to make sure no references point to it. For example:

function a:doSth()
    a = nil
end

That will release the reference by a, there is still a reference from self but that automatically goes out of scope when the function ends. After the function call, {1,2,3} will get collected by the gc on the next cycle assuming nothing else refers to that table.

greatwolf
  • 20,287
  • 13
  • 71
  • 105
  • But how to directly get the memory address holds by the table 'a' and free the memory just like 'delete' in C++? Thanks. – NiklausTseng Jan 21 '15 at 08:14
  • 1
    The answer is you don't. Lua is a garbage collected scripting language and part of that safety means not allowing you to manually muck around with resources at that low of a level. The closest you can get is to `nil` out the references and call `collectgarbage()` afterwards. – greatwolf Jan 21 '15 at 08:51
  • You don't need to set variables to `nil`. You just need to stop referencing the table. One way is to limit the scope of the variable. Another way is to set it to a new table, which allows you to write code that assumes it is always referencing _some_ table. – Tom Blodget Jan 22 '15 at 02:35
1

You can do this:

a = nil
collectgarbage()

However I don't recommend running a full garbage collection cycle just to liberate 1 table. Garbage collection takes time and it is better to leave Lua to run it when it sees fit.

kikito
  • 51,734
  • 32
  • 149
  • 189