tl;dr バージョン: グローバル変数にアクセスする場合、Lua 状態のシャットダウン中にガベージ コレクション メタメソッドは安全ですか? ローカルのアップ値はどうですか?
がlua_State
で閉じられるとlua_close
、Lua のドキュメントには、すべてのオブジェクトが削除されると書かれています。また、関連するガベージ コレクション メタメソッドが呼び出されることが保証されていることも示しています。
偉大な。
ただし、このパラダイムでは不明な GC メタメソッドの使用例が 2 つあります。
収集可能な値を格納するローカル変数を使用する GC メタメソッドがある場合はどうでしょう。たとえば、文字列、関数などです。つまり、GC メタメソッドは次のように定義されます。
local some_string = "string" function mt:__gc() --[[Do something with some_string]] end
この場合はどうなりますか?
some_string
回収は可能ですか?メタテーブルがあるオブジェクトが通常の状況で収集されている場合、これは不可能であることはわかっています。some_string
Lua は、GC 関数自体が収集されるまでの値が保持されることを保証します。しかし、すべてのオブジェクトが によって破棄されている
lua_close
ため、関数が破棄される前に GC 関数の上位値が破棄される可能性はありますか? (これはあらゆる種類の問題を引き起こす可能性があるため) そうではないと思いますが、私が考えていることではなく、本当の答えを探しています。GC メタメソッドで多くの問題が発生するため、#1 が問題になる可能性は低いことを認めます。ただし、これはまったく別の問題です。
local some_string = "string" function mt:__gc() print(some_string) end
これは#1のように見えますが、そうではありません。なんで?グローバル変数にアクセスするためです。つまり、
print
.関数と格納されている値との間には直接的な関連はありません
print
(ケース 1 とは異なり、some_string
は明らかに関数の上位値です)。そのため、print
Lua 状態のシャットダウン中に関数を呼び出す前に が収集される可能性があります。
問題はこれです:ガベージ コレクション メタメソッドが、 Lua 状態のシャットダウン中にグローバル テーブルから何かを使用することは安全ですか ( に対してグローバル テーブルの意図的な妨害行為の可能性を無視します)。print = nil
それとも、原則として、それらが触れる関数やデータを常に明示的にローカルにする必要がありますか? 問題を回避するのに十分でしょうか?