lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Apr 30, 2011, at 11:22 AM, Lorenzo Donati wrote:

> Sorry, I really miss something here. I don't understand what memory leak you and Henk are talking about.
> 
> Would you like please giving some hints/pointers on the subject, thanks

In versions of Lua prior to 5.2, a semi-weak table such as this where the keys are weak but the values are strong will always mark all of the values before deciding which keys are unreferenced. This means that if a value leads back to a key, even if that's the only path back to the key, the key and value will never get collected. So, for example:

privateData = setmetatable( {}, { __mode = 'kv' } )

x = { }
xprivate = { public = x }
privateData[ x ] = xprivate

-- Now drop the references...

x = nil
xprivate = nil

The values still live forever because of the reference from privateData even though nothing can ever reach those values.

And one doesn't have to have a direct link back from the key to the value. The following would create 4 unreachable but immortal objects in Lua 5.1:

privateData = setmetatable( {}, { __mode = 'kv' } )

x = { }
y = { }
xprivate = { other = y }
yprivate = { other = x }
privateData[ x ] = xprivate
privateData[ y ] = yprivate

-- Now drop the references...

x = nil
xprivate = nil
y = nil
yprivate = nil

The basic lesson is that in Lua 5.1 and earlier, you want to be cautious when creating semi-weak tables. (Or at least weak-keyed tables. I can't remember whether weak-valued tables have issues.) In 5.2, this is less of a problem but it does invoke potentially quadratic time complexity code during the atomic step of the collector, so you trade uncollectable data for potential time hits.

Mark