tl; dr version:如果它访问全局变量,在Lua状态关闭期间是垃圾收集元方法安全吗?那么本地的价值观呢?
当使用lua_State
关闭lua_close
时,Lua文档会说明all of the objects are deleted。并且它表示保证调用任何相关的垃圾收集元方法。
大
但是,有两种可能的GC元方法用例在这种范例下是不确定的:
如果您的GC元方法使用存储可收集值的局部变量,该怎么办?比方说,一个字符串,一个函数等。也就是说,你的GC元方法定义如下:
local some_string = "string"
function mt:__gc() --[[Do something with some_string]] end
在这种情况下会发生什么?是否可以收集some_string
?我知道如果在正常情况下正在收集metatable所在的对象,那么这是不可能的。 Lua将保证some_string
的值将保留,直到GC函数本身被收集。
但是由于所有对象都被lua_close
破坏,因此在函数出现之前,GC函数的upval可能会被破坏吗?我认为不是(因为这可能导致各种问题),但我正在寻找真正的答案,而不是我的想法。
我承认#1不太可能成为问题,因为它会在GC元方法中产生许多问题。但是,这是一个完全不同的问题:
local some_string = "string"
function mt:__gc() print(some_string) end
这看起来像#1,但事实并非如此。为什么?因为它访问全局变量。即,print
。
函数与print
中存储的任何值之间没有直接关联(与案例1不同,其中some_string
显然是函数的升值)。因此,在Lua状态关闭期间调用函数之前可以收集print
。
问题是这样:垃圾收集元方法是否安全使用全局表中的任何内容(忽略了故意破坏全局表的可能性{{1在Lua状态关闭期间?或者,作为一般规则,他们是否应始终明确地将任何功能或数据与本地接触?这足以避免问题吗?
答案 0 :(得分:4)
可以从__gc
方法访问的任何数据都可以安全访问;这包括本地和可访问的表,例如_G
,其中包含print
。
可能存在的问题是(未加载)C库;这会影响Lua 5.1,并在Lua 5.2.1中得到修复。请参阅patch for "Finalizers may call functions from a dynamic library after the library has been unloaded"。