我在C#应用程序中使用最新版本的LuaInterface(http://code.google.com/p/luainterface/)。我遇到了一个问题,即Lua类无法清除ObjectTranslator'对象'和'objectsBackMap'字典中的内部引用,导致内存使用量不断增长。
以下代码说明了问题:
public class Program
{
public static void Main()
{
Lua lua = new Lua();
string f = @"
return function(myClass, dotNetObject)
local f = function() dotNetObject:TestMethod() end
myClass:StoreFunction(f);
end";
var result = lua.DoString(f)[0] as LuaFunction;
MyClass testItem = new MyClass();
for (int i = 0; i < 50; i++)
{
DotNetObject o = new DotNetObject();
result.Call(testItem, o);
}
lua.DoString("collectgarbage()");
ObjectTranslator translator = (ObjectTranslator)typeof(Lua).GetField("translator", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(lua);
Console.WriteLine("Object count: " + translator.objects.Count);
//Prints out 51. 50 of these items are instances of 'DotNetObject', despite them being unreachable.
//Forcing a .NET garbage collection does not help. They are still being held onto by the object translator.
}
public class MyClass
{
public void StoreFunction(LuaFunction function)
{
//I would normally save off the function here to be executed later
}
}
public class DotNetObject
{
public void TestMethod()
{
}
}
}
当匿名函数(local f = ...)从外部作用域创建涉及.NET对象的闭包时,就会出现问题。只要Lua解释器保持活动状态,我创建的50个DotNetObject类实例将永远不会被垃圾收集,即使在Lua中强制执行GC时也是如此。
在MyClass.StoreFunction中手动处理LuaFunction(function.Dispose())对象解决了这个问题,但这是不可取的,因为在我的实际应用程序中我不知道函数何时执行 - 或者它是否曾经将。强迫我处理LuaFunction改变了应用程序的整个架构,这样我基本上通过处理包含LuaFunction的对象和包含该对象的对象来进行手动内存管理,一直到链。
那么,这是LuaInterface中的错误,还是我错误地使用了库?非常感谢任何建议,谢谢!