2016-06-15 21 views
0

私は.NET 4.6の下でMoonSharp(1.6.0、ちょうど更新され、問題もあった)を使用しています。MoonSharp DoStringがメモリをリークしているのはなぜですか?

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

それは私が〜1.5キロバイトはプログラムで使用されている追加のLuaCore.Call("any code")を呼び出すたびのように思える:私は、次のC#のコードを持っています。これは、any codestuff = nilであるため、「任意のコード」となります。
これを1秒間に約3500回呼び出すと、5秒ごとに25メガバイトがさらに使用され、1秒あたりの呼び出しはマシンの電源によって異なります。 1回の更新で複数の呼び出しが使用されるため、プログラムのメモリ使用量も高速になります(テスト済み)。 5分後に、私はOutOfMemoryExceptionを取得しました(1.4GBを使用)。
1.5GBのRAMを使用して、アプリケーションでヒープのスナップショットを撮りました。インタプリタは、呼び出された各ソースコードを保存しているか、VSの診断ツールでそのように見えます。
Memory heap from snapshot

MoonSharpが各呼び出しで多くのデータを格納するのはなぜですか?

+1

メモリプロファイラを実行し、メモリに保持されているオブジェクトとそのオブジェクトを保持しているオブジェクトを確認します。それ以降は、あなたの質問にもっと簡単に答えてくれるでしょう。 –

+0

ラムに保持されたオブジェクトの詳細とスクリーンショットを追加しました。 – Exec

答えて

1

単純な答え:あなたがしようとしているものに対して間違ったAPIを(おそらく)呼びます。 DoStringは、指定されたスクリプトコンテキスト内で指定されたコードをロードして実行します。同じコードを何度も渡すと、それ以上のコピーがロードされます。

だから、あなたが達成しようとしているかに応じて2つの選択肢がある:

  1. はさまざま毎回あるスクリプトを呼び出すためにLuaCore.Callを使用している:Script.RunString(code)を使用する - それは、静的メソッドだとdoesnの」実行中の状態を保持する
  2. LuaCore.Callを使用して、同じスクリプトを何度も呼び出します。DynValue ret = script.LoadString(code)を一度だけ呼び出し、次にscript.Call(ret)を繰り返し呼び出します。

これが役に立ちます。

+0

残念ながらどちらも助けられませんでした。最初のアプローチでは、その関数の外でコンテキストやデータを作成することはできません。わずかな変更があるため、各呼び出しで同じコードを渡したければ、2番目のコードは正しく機能します。 – Exec

+1

次に、インスタンス間でデータを共有するために、個別のスクリプトオブジェクトを作成し、「裸の」テーブル(または選択したユーザーデータ)を使用することが唯一の方法です。関数は特定のスクリプトに属しているため、通常の表は共有できません。 Scriptオブジェクトを作成するのは軽量な操作ではないため、すべてのフレームを高価にする可能性は高くなりますが、これは疑問です。最初にフレームごとにスクリプトを少し変更しているのはなぜですか? –

+0

ちょっとした文脈の変更や位置付けなどです。そのため、スクリプトをlua関数に昇格させ、パラメータを指定してCall()を呼び出すと、呼び出されるたびに保存されず、メモリ(およびパフォーマンス)が節約されます。 – Exec

関連する問題