2016-06-15 132 views
0

我在.NET 4.6下使用了MoonSharp(1.6.0,刚刚更新,之前也有问题)。我有以下的C#代码:为什么MoonSharp DoString泄漏内存?

public class LuaCore { 
    public static Script script = new Script(); 
    public static DynValue Call(string func) 
    { 
     return script.DoString(func); 
    } 
} 

好像每当我打电话LuaCore.Call("any code")附加〜1.5千字节的程序所使用。这也发生在any codestuff = nil,因此“任何代码”。
当这被称为每秒约3500次时,每五秒钟会使用一次额外的25兆字节,每秒的呼叫取决于机器的功率。由于每次更新都会使用多个调用,程序的内存使用量也会增加得更快(测试过)。 5分钟后,我得到一个OutOfMemoryException(使用1.4GB)。
我用应用程序使用1.5GB的RAM拍了堆的快照。看起来解释器正在存储被调用的每个源代码,或者它看起来像使用VS的诊断工具。
Memory heap from snapshot

为什么MoonSharp在每次调用时都存储那么多数据?

+1

取内存分析器并查看内存中保存了哪些对象以及谁拥有它们。在那之后回答你的问题会容易得多 –

+0

我已经在RAM中添加了一些细节和截图。 – Exec

回答

1

简单的回答:你(很可能)正在为你正在尝试做的事调用错误的API。 DoString在指定的脚本上下文中加载指定的代码并运行它。如果你一遍又一遍地传递相同的代码,你只需要加载越来越多的副本。

所以有两种选择,取决于你想要达到的目的:

  1. 您正在使用LuaCore.Call调用脚本不同的是,每次:使用Script.RunString(code) - 这是一个静态方法,并没有按”保存任何状态从一次运行到另一次运行
  2. 您正在使用LuaCore.Call反复调用相同的脚本:一次调用DynValue ret = script.LoadString(code),然后一次又一次调用script.Call(ret)

希望这会有所帮助。

+0

不幸的是没有帮助。第一种方法不允许我在该函数之外创建任何上下文和数据,第二个方法只有在每次调用期间要传递完全相同的代码时才起作用,因为这些代码有一些小的变化。 – Exec

+1

然后,您唯一的机会是创建单独的脚本对象,并使用“裸”表(或您选择的用户数据)来在实例之间共享数据。请注意,您不能共享普通表,因为函数属于特定的脚本。 创建一个脚本对象不是一个轻量级的操作,所以这样做每帧都可能太昂贵了..但是这引出了一个问题 - 为什么你每次对脚本进行一些小改动? –

+0

只是一些上下文的变化,位置等。因此,将脚本提升为lua函数,然后使用参数调用()它不会在每次调用时都存储它们,从而节省内存(也许性能)? – Exec