C# から lua コードをコンパイルするために NLua を使用しています。問題は、C# で作成された LuaTables を Lua ガベージ コレクターで完全に破棄できないことです。
サンプルコードは次のとおりです。
public static List<LuaTable> TempTables = new List<LuaTable>();
static void Main(string[] args)
{
using (Lua lua = new Lua())
{
double mem = (double)lua.DoString("return collectgarbage(\"count\")")[0];
for (int i = 0; i < 100000; i++)
{
LuaTable lt = NewTab(lua);
}
mem = (double)lua.DoString("return collectgarbage(\"count\")")[0];
foreach (LuaTable lt in TempTables)
{
lt.Dispose();
}
TempTables.Clear();
lua.DoString("collectgarbage()");
mem = (double)lua.DoString("return collectgarbage(\"count\")")[0];
}
}
public static LuaTable NewTab(Lua l)
{
LuaTable lt = (LuaTable)l.DoString("return {}")[0];
TempTables.Add(lt);
return lt;
}
このコードは単純に 100,000 個のテーブルを作成し、それを C# で破棄し、lua でガベージ コレクションを呼び出します。使用メモリは変数「mem」で調べることができます。その結果、「mem」は 22.04Kb から約 22.04Kb に増加します。1000キロバイト。これは、この方法で破棄するとメモリ リークが発生することを意味します。
ただし、LuaTable をすぐに破棄すると、次のようになります。
for (int i = 0; i < 100000; i++)
{
LuaTable lt = NewTab(lua);
lt.Dispose();
}
それはうまくいきます。「mem」は同じ +-1Kb のままです。
なぜそうなのですか?Lua gc から完全にアクセスできるようにするには、Lua オブジェクトをどのように破棄すればよいですか?