2016-06-15 129 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