【问题标题】:in Lua, should I assign all table element to nil when it's not used?在 Lua 中,我应该在不使用时将所有表元素分配给 nil 吗?
【发布时间】:2014-02-12 03:26:25
【问题描述】:

例如,我这样创建了一个表

myTable = {}
for n=1,5
    local item = {
        name = "item"..n,
        id = n,
    }
    myTable[n] = item
end

当这个表不再使用时,为了释放这个表给垃圾回收器,

是否需要循环遍历表以将每个元素分配给 nil?

for n=1,5
    myTable[n] = nil
end

或者我只需要将表分配为 nil?

myTable = nil

除了上述之外,如果表格元素具有分配给其他表格的某些属性,我是否也需要单独将它们归零?

for n=1,5
    myTable[n].someTable = nil
    myTable[n] = nil
end
myTable = nil

【问题讨论】:

    标签: memory-leaks lua garbage-collection lua-table


    【解决方案1】:

    只需分配myTable = nil 就可以了。你可以像这样测试它,使用__gc 元方法:

    myTable = {}
    for n=1,5 do
        local item = {
            name = "item"..n,
            id = n,
        }
        setmetatable(item, {__gc = function (self) print("item " .. n .." collected") end})
        myTable[n] = item
    end
    
    myTable = nil
    
    collectgarbage()
    

    输出:

    item 5 collected
    item 4 collected
    item 3 collected
    item 2 collected
    item 1 collected
    

    这意味着所有item 表都由垃圾收集器收集。

    【讨论】:

    • 我的最后一个问题怎么样:如果表项具有分配给其他表的属性,我是否也需要 nil ?还是只用myTable = nil 就行了?
    • @Joe 同样,myTable = nil 也可以。 Lua 垃圾收集器知道该表中不再引用另一个表,并且当它没有在任何地方引用时最终会收集它。
    【解决方案2】:

    一切都是关于参考。即使您已将引用表的变量设置为 nil,如果有另一个对表的引用,垃圾收集器也不会释放内存。因为表仍在“使用中”。

    例如:

    myTable = {}
    myOtherTable = myTable
    for n=1,5 do
        local item = {
            name = "item"..n,
            id = n,
        }
        myTable[n] = item
    end
    
    print(myTable)
    myTable=nil
    print(myTable)
    print(myOtherTable)
    
    --OUTPUT
    --table: 0x8ebb40
    --nil
    --table: 0x8ebb40
    

    如果一个表在任何地方(甚至在另一个表中)被引用,它不会被释放。

    【讨论】:

    • 是的,我明白你的意思,但这与我的问题有点不同。
    • 只是为了重新思考这个问题。简而言之:如果表格上没有元素或表格本身没有引用该表格,则如果您将其 nil 则将被收集,如于浩所示。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-05
    • 2011-01-11
    • 1970-01-01
    • 2010-10-20
    • 1970-01-01
    相关资源
    最近更新 更多