Lua: Make the Lua garbage collector collect unique(as) objects/tables referenced by a table

Asked

Viewed 145 times

-4

Let’s assume I have a table that stores information on 200 tables,

local rand = math.random;

--[=[
  - Uma tabela que armazena uma informação
  - sobre tabelas específicas
  - (Cada campo contém uma chave que referencia uma tabela,
  - e um valor sendo um número randômico de 0 à 50, por exemplo:
  - tables[ {} ] = rand(0, 50))
  ]=]
tables = {};


-- Armazena um número randômico para uma tabela
local function init(t)
    tables[t] = rand(0, 50);
end

for i = 1, 2e2 do
    init {};
end

It looks okay, but the table referenced by tables, in the end, it receives 200 fields that, together, reference 200 tables that needed to be collected by garbage collector moon.

Q: 200 fields? Each one references a table?
A: See the loop and the call init {}. A table is being declared and referenced in the first argument of the referenced function in init. This function defines a field in tables, its key being the table of the first argument of the call, and its value being a random number. That is, the defined field key references a table.

Q: Why the 200 declared tables needed to be collected and why they could not be collected?
A: Because they will not be recognized by my program. The 200 tables in this case have nothing to do with the program. Imagine if they were tables instantiated by a class. This class could have a table that stores private data for its instances. For this, each field of this table contains a key that references the instance (respectively a table), and the value of each field equals the data of its instances. But what if this private data table is preventing that instances (respectively tables) are collected by the Moon’s trash? For example, a case where the private data table is the only one that is referencing a certain table and still storing its data. The intention is that these unique tables referenced within the private data table be collected as garbage.

While the table referenced by tables is not collected as garbage by the Moon, 200 unused tables will not be collected as well. In this example code the program will finish running and the table will probably be collected as garbage by the Moon, but this is not the goal, as said, is a example, The real situation wouldn’t be like this. In the real situation, the program will continue running (and asynchronously) until it is stopped for some time.

Is there any way to make the unique tables referenced by table fields tables be collected as garbage by the Moon in this case? I also wondered if this is possible only in versions of the Moon, larger than 4.0.

1 answer

3


In version 5.0 (except in the versions below, I believe) or above there is a way, making the table tables in a Weak table. Actually the table won’t be a Weak table, there will be an option to make field references weak. This will cause the Lua garbage collector to ignore the presence of each reference in the keys and values, only in the keys or only in the values, depending on the value of this option.

According to the section 2.9.2 from the Lua 5.0 ref. manual, when a table has Weak Keys (or weak keys), the keys of your fields can be collected as garbage. When the key or value of a field is collected(a), that same field is removed from the table (the key space and the value), and this makes sense since the key/value of the field will probably be nil, or typically nothing... from section 2.9.2:

In any case, if either the key or the value is collected, the Whole pair is Removed from the table.

That translating to Portuguese would be:

In any case, if the key or value is collected, the entire pair is removed from the table.

When a table has Weak values (or weak values), so the values of your fields can also be collected as garbage. The same table can have both weak keys(s) and weak values.

This option that allows us to obtain Weak Keys or Weak values can be defined in the field __mode of a table’s metatable, and the table will be affected by the option. The option should be a string, which contains the byte 107 ("k"), activates weak key mode, and containing the byte 118 ("v") activates weak values mode.

In the example code, the field __mode might be something like 'k', since it makes possible the tables referenced in the fields of tables to be collected by the Moon trash. Containing 'v' also makes it possible to collect the values...

setmetatable(tables, {
    __mode = 'kv'
});

Remembering that unnecessary objects (or tables) (as) can be collected only later, according to two numbers used to control the garbage collector circle: section 2.9. Or, unless one of those numbers Threshold be updated to run the garbage collector at the same time. If this were done, it would be good to undo it if it were not a test, but I think it is not possible to know the number Threshold current, but it is possible to choose a good number as before. Section 5.1 of the manual (collectgarbage is documented at the top).

 collectgarbage();

Browser other questions tagged

You are not signed in. Login or sign up in order to post.