Версия tl; dr :является безопасным метаметодом сборки мусора во время выключения состояния Lua, если он обращается к глобальным переменным? Как насчет локальных значений up -?
Когда lua_State
закрывается с помощью lua_close
, в документации Lua говорится, что все объекты удаляются . И это говорит о том, что любые ассоциированные метаметоды сборки мусора -гарантированно будут вызываться.
Отлично.
Однако есть два возможных варианта использования метаметодов сборщика мусора, которые в этой парадигме неясны:
Что делать, если у вас есть метаметод GC, который использует локальную переменную, в которой хранится собираемое значение. Скажем, строка, функция и т. д. То есть ваш метаметод GC определяется как:
local some_string = "string"
function mt:__gc() --[[Do something with some_string]] end
Что происходит в этом случае? Можно ли собрать some_string
? Я знаю, что если объект, на котором находится метатаблица, собирается при нормальных обстоятельствах, то это невозможно. Lua гарантирует, что значение some_string
останется до тех пор, пока не будет собрана сама функция GC.
Но поскольку все объекты уничтожаются с помощью lua_close
, возможно ли, что верхние значения функции GC могут быть уничтожены до того, как будет уничтожена сама функция? Я не думаю, что это (, так как это может вызвать всевозможные проблемы ), но я ищу реальный ответ, а не то, что я думаю.
Я признаю, что маловероятно, что #1 будет проблемой, так как это создаст много проблем с метаметодами сборщика мусора. Однако это совсем другое дело:
local some_string = "string"
function mt:__gc() print(some_string) end
Это выглядит как #1, но это не так. Почему? Потому что он обращается к глобальной переменной . А именно print
.
Нет прямой связи между функцией и любым значением, хранящимся в print
(. в отличие от случая 1,где some_string
явно является верхним значением функции ). Таким образом, print
можно собрать перед вызовом функции во время выключения состояния Lua.
Вопрос в том, :является ли безопасным для метаметода сборки мусора когда-либо использовать что-либо из глобальной таблицы (, игнорируя возможность преднамеренного саботажа глобальной таблицы по отношению -к -висprint = nil
)во время выключения состояния Lua? Или, как правило, они должны всегда явно делать любые функции или данные, к которым они прикасаются, локальными? Будет ли этого достаточно, чтобы избежать проблем?