2016-06-15 4 views
0

Я использую MoonSharp (1.6.0, только что обновлено, возникла проблема перед ним тоже) в .NET 4.6. У меня есть следующий код 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 code - stuff = nil, следовательно, «любой код».
Когда это называется около 3500 раз в секунду, каждые 25 секунд используются дополнительные 25 мегабайт, а вызов в секунду зависит от мощности аппарата. Поскольку для каждого обновления будет использоваться несколько вызовов, использование памяти в программе также увеличится быстрее (протестировало это). Через 5 минут я получаю OutOfMemoryException (с использованием 1,4 ГБ).
Я сделал снимок кучи с приложением, используя 1,5 ГБ оперативной памяти. Кажется, что интерпретатор хранит каждый исходный код, который был вызван, или он выглядит так, как с помощью диагностических инструментов VS.
Memory heap from snapshot

Почему MoonSharp хранит столько данных при каждом звонке?

+1

Возьмите профайлер памяти и посмотрите, какие объекты хранятся в памяти и кто их удерживает. После этого вам будет намного легче ответить на ваш вопрос. –

+0

Я добавил некоторые детали и скриншот с объектами, хранящимися в памяти. – Exec

ответ

1

Простой ответ: вы (вероятно) вызываете неправильный API за то, что вы пытаетесь сделать. DoString загружает указанный код внутри указанного контекста скрипта и запускает его. Если вы передаете один и тот же код снова и снова, вы просто загружаете все больше и больше его копий.

Таким образом, есть два варианта, в зависимости от того, что вы пытаетесь достичь:

  1. Вы используете LuaCore.Call для вызова скрипта, который отличается каждый раз: использовать Script.RunString(code) - это статический метод и Безразлично» t сохранить любое состояние от одного запуска до другого
  2. Вы используете LuaCore.Call для вызова одного и того же сценария снова и снова: звоните DynValue ret = script.LoadString(code) один раз, а затем script.Call(ret) снова и снова.

Надеюсь, это поможет.

+0

К сожалению, ни одна из них не помогла. Первый подход не позволяет мне иметь какой-либо контекст и данные, сделанные вне этой функции, а второй будет работать, если я захочу передать точно такой же код во время каждого вызова, который у меня нет, так как есть небольшие изменения. – Exec

+1

Тогда ваш единственный шанс создать отдельные объекты Script и использовать «голую» таблицу (или пользовательские данные по вашему выбору) для обмена данными между экземплярами. Обратите внимание: вы не можете делиться обычными таблицами, потому что функции принадлежат определенному скрипту. Создание объекта Script не является легкой операцией, поэтому сделать так, чтобы каждый кадр был слишком дорогим .. но это задает вопрос - почему вы вносите небольшие изменения в сценарий в каждом кадре? –

+0

Просто некоторые контекстные изменения, позиции и т. Д. Так что продвижение сценария в функцию lua, а затем Call() - с его параметрами не будет их хранить каждый раз, когда он вызывается, экономя память (а может и производительность)? – Exec

Смежные вопросы