有关Lua状态关闭和垃圾回收元方法的规则

当使用lua_close关闭lua_State时,Lua文档说所有对象都将被删除。它还表示,任何相关的垃圾回收元方法都有保证会被调用。

但是,这种范例下有两种可能的GC元方法用例不太确定:

  1. 如果您有一个GC元方法,它使用存储可垃圾收集值的局部变量,例如,字符串、函数等。也就是说,您的GC元方法被定义为此形式:

    local some_string = "string"
    function mt:__gc() --[[Do something with some_string]] end
    

    在这种情况下会发生什么? some_string是否有可能被收集?我知道,如果元表所在的对象在正常情况下被收集,那么这种情况是不可能的。Lua将保证some_string的值保持不变,直到GC函数本身被收集。

但是,由于所有对象都将被销毁,因此在函数被销毁之前是否可能销毁GC函数的upvalue?我认为不可能(因为这可能会导致各种问题),但我正在寻找真正的答案,而不是我认为的答案。

  1. 我承认这是不太可能出现问题的问题,因为它会产生许多与GC元方法有关的问题。但是,这是完全不同的问题:

    local some_string = "string"
    function mt:__gc() print(some_string) end
    

    它看起来像#1,但并不是。为什么?因为它访问了一个全局变量。即,打印。

    函数和存储在打印中的任何值之间没有直接关联(与情况1明显是该函数的upvalue“some_string”不同)。因此,在Lua状态关机期间在调用函数之前可以收集“print”。

问题是:在Lua状态关闭期间,垃圾回收元方法使用来自全局表的任何东西是安全的(忽略了全局表与print= nil的故意破坏的可能性)?或者,作为一般规则,它们总是显式地使它们触摸的任何函数或数据本地的?这将是否足以避免问题?

点赞
用户33252
用户33252

任何可以从__gc方法中访问的数据都是安全的访问;这包括可访问的局部变量和表,例如 _G,其中包含print

可能存在问题的是已加载或未加载的 C 库,这会影响 Lua 5.1,但在 Lua 5.2.1 中已解决。请参见“最终器可能在动态库被卸载后调用函数”的修补程序

2012-08-11 01:51:32