2016-06-15 9 views
0

Ich benutze MoonSharp (1.6.0, gerade aktualisiert, hatte das Problem schon vorher) unter .NET 4.6. Ich habe den Code # folgenden C:Warum verliert MoonSharp DoString Speicher?

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

Es scheint, als wenn ich nenne LuaCore.Call("any code") zusätzliche ~ 1,5 Kilobyte durch das Programm verwendet werden. Dies geschieht auch dann, any code ist stuff = nil, daher "jeder Code".
Wenn diese ca. ~ 3500 Mal pro Sekunde aufgerufen wird, werden weitere 25 Megabyte alle fünf Sekunden verwendet, und der Anruf pro Sekunde hängt von der Leistung des Geräts ab. Da pro Update mehrere Aufrufe verwendet würden, würde auch die Speichernutzung des Programms schneller zunehmen (dies getestet). Nach 5 Minuten bekomme ich eine OutOfMemoryException (mit 1.4GB benutzt).
Ich habe einen Snapshot des Heaps mit der App mit 1,5 GB RAM gemacht. Es scheint, dass der Interpreter jeden Quellcode speichert, der aufgerufen wurde, oder es sieht so aus mit den Diagnosewerkzeugen von VS.
Memory heap from snapshot

Warum speichert MoonSharp bei jedem Anruf so viele Daten?

+1

Nehmen Sie Speicherprofiler und sehen Sie, welche Objekte im Speicher gehalten werden und wer sie hält. Es wird viel einfacher sein, Ihre Frage danach zu beantworten –

+0

Ich habe einige Details hinzugefügt und einen Screenshot mit den Objekten in Ram gehalten. – Exec

Antwort

1

Einfache Antwort: Sie rufen (wahrscheinlich) die falsche API für das, was Sie versuchen zu tun. DoString lädt den angegebenen Code in den angegebenen Skriptkontext und führt ihn aus. Wenn Sie den gleichen Code immer wieder übergeben, laden Sie immer mehr Kopien davon.

So gibt es zwei Möglichkeiten, je nachdem, was Sie erreichen wollen:

  1. Sie verwenden LuaCore.Call ein Skript aufrufen, die verschiedene jedes Mal ist: Verwenden Sie Script.RunString(code) - es ist eine statische Methode und doesn‘ t keinen Zustand von einem Lauf zum anderen beibehalten
  2. Sie verwenden LuaCore.Call, um dasselbe Skript immer wieder aufzurufen: Rufen Sie zuerst einmal DynValue ret = script.LoadString(code) und dann wieder script.Call(ret) auf.

Hoffe, das hilft.

+0

Leider auch nicht geholfen. Der erste Ansatz lässt mich keinen Kontext und Daten außerhalb dieser Funktion machen, der zweite würde nur funktionieren, wenn ich bei jedem Aufruf genau denselben Code weitergeben wollte, was ich nicht tue, da es ein paar kleine Änderungen gibt. – Exec

+1

Dann besteht die einzige Möglichkeit darin, separate Skriptobjekte zu erstellen und eine "nackte" Tabelle (oder einen Benutzerdatenspeicher Ihrer Wahl) für die gemeinsame Nutzung von Daten zwischen Instanzen zu verwenden. Beachten Sie, dass Sie keine normalen Tabellen freigeben können, da Funktionen zu einem bestimmten Skript gehören. Das Erstellen eines Script-Objekts ist keine leichte Operation, daher ist es wahrscheinlich, dass jeder Frame zu teuer ist. Aber das wirft die Frage auf - warum machen Sie kleine Änderungen an dem Skript in jedem Frame an erster Stelle? –

+0

Nur einige kontextuelle Änderungen, Positionen, usw. Also das Script auf eine Lua-Funktion zu promoten und es dann mit Parametern aufzurufen, hätte sie nicht bei jedem Aufruf gespeichert, was Speicher (und vielleicht auch Performance) spart? – Exec

Verwandte Themen