关于Lua状态关闭和垃圾收集元方法的规则
tl;dr版本:如果垃圾收集元方法访问全局变量,它在Lua状态关闭期间是否安全?本地的up值呢关于Lua状态关闭和垃圾收集元方法的规则,lua,Lua,tl;dr版本:如果垃圾收集元方法访问全局变量,它在Lua状态关闭期间是否安全?本地的up值呢 当使用lua\u close关闭lua\u状态时,lua文档会这样说。它说任何相关的垃圾收集元方法都保证被调用 太好了 然而,在这种范式下,GC元方法有两种可能的用例是不确定的: 如果您有一个GC元方法,它使用存储可收集值的局部变量,该怎么办。例如,字符串、函数等。也就是说,您的GC元方法定义如下: local some_string = "string" function mt:__gc() --
当使用
lua\u close
关闭lua\u状态时,lua文档会这样说。它说任何相关的垃圾收集元方法都保证被调用
太好了
然而,在这种范式下,GC元方法有两种可能的用例是不确定的:
如果您有一个GC元方法,它使用存储可收集值的局部变量,该怎么办。例如,字符串、函数等。也就是说,您的GC元方法定义如下:
local some_string = "string"
function mt:__gc() --[[Do something with some_string]] end
在这种情况下会发生什么?是否可以收集某些\u字符串
?我知道,如果元表所在的对象在正常情况下被收集,那么这是不可能的。Lua将保证some_string
的值将保留,直到收集到GC函数本身
但是,由于所有对象都被lua\u close
销毁,GC函数的upvalues是否可能在函数被销毁之前被销毁?我不认为是这样(因为这可能导致各种各样的问题),但我在寻找真正的答案,而不是我所想的
我承认#1不太可能成为问题,因为它会在GC元方法中产生许多问题。然而,这是一个完全不同的问题:
local some_string = "string"
function mt:__gc() print(some_string) end
这看起来像#1,但不是。为什么?因为它访问一个全局变量。即,打印
函数与print
中存储的任何值之间没有直接关联(与案例1不同,某些字符串显然是函数的向上值)。因此,在Lua状态关闭期间调用函数之前,可以收集print
问题是:在Lua状态关闭期间,垃圾收集元方法使用全局表中的任何内容(忽略故意破坏全局表vis-a-visprint=nil
)是否安全?或者,作为一般规则,他们是否应该总是明确地将他们接触的任何函数或数据设置为本地?这足以避免问题吗?可以从\uu gc
方法访问的任何数据都是安全的;这包括局部变量和可访问的表,如\u G
,其中包含打印
可能出现的问题是(未加载的)C库;这会影响Lua5.1,并在Lua5.2.1中固定。请参阅。我不知道那个错误。毕竟,我可能必须升级到5.2。我想你不知道LuaJIT是否有这个问题;它的GC是基于Lua5.1的,所以这可能是一个问题。另一方面,由于有FFI,所以在LuaJIT中使用库的动机较小,并且简单的Lua代码相当快。