Сборка мусора Lua и пользовательские данные C

В моем игровом движке я открываю свои объекты Vector и Color для Lua, используя пользовательские данные.

Теперь для каждого даже локально созданного вектора и цвета из скриптов Lua использование памяти Luas немного увеличивается, оно не падает, пока не запустится сборщик мусора.

Сборщик мусора вызывает небольшой лаг в моей игре.

Разве объекты Vector и Color не должны быть немедленно удалены, если они используются только в качестве аргументов? Например, так: myObject:SetPosition( Vector( 123,456 ) )

Сейчас это не так - использование памяти Lua увеличивается до 1,5 МБ в секунду, затем происходит всплеск задержки, и он возвращается примерно к 50 КБ.

  • Как я могу решить эту проблему, она вообще разрешима?

person Jarx    schedule 09.02.2011    source источник


Ответы (4)


Вы можете запустить lua_setgcthreshold(L,0) для принудительной немедленной сборки мусора после выхода из функции.

Изменить: для 5.1 я вижу следующее:

int lua_gc (lua_State *L, int what, int data);

Controls the garbage collector.

This function performs several tasks, according to the value of the parameter what:

    * LUA_GCSTOP: stops the garbage collector.
    * LUA_GCRESTART: restarts the garbage collector.
    * LUA_GCCOLLECT: performs a full garbage-collection cycle.
    * LUA_GCCOUNT: returns the current amount of memory (in Kbytes) in use by Lua.
    * LUA_GCCOUNTB: returns the remainder of dividing the current amount of bytes of memory in use by Lua by 1024.
    * LUA_GCSTEP: performs an incremental step of garbage collection. The step "size" is controlled by data (larger values mean more steps) in a non-specified way. If you want to control the step size you must experimentally tune the value of data. The function returns 1 if the step finished a garbage-collection cycle.
    * LUA_GCSETPAUSE: sets data as the new value for the pause of the collector (see §2.10). The function returns the previous value of the pause.
    * LUA_GCSETSTEPMUL: sets data as the new value for the step multiplier of the collector (see §2.10). The function returns the previous value of the step multiplier.
person BMitch    schedule 09.02.2011
comment
Однако это было удалено в 5.1. Как это можно воспроизвести? - person GManNickG; 09.02.2011

В Lua единственный способ удалить такой объект, как пользовательские данные, — это сборщик мусора. Вы можете вызвать сборщик мусора напрямую, как написал B Mitch (используйте lua_gc(L, LUA_CGSTEP, ...)), но нет гарантии, что именно ваш временный объект будет освобожден.

Лучший способ решить эту проблему — избежать создания временных объектов. Если вам нужно передать фиксированные параметры таким методам, как SetPosition, попробуйте изменить API так, чтобы он также принимал числовые аргументы, избегая создания временного объекта, например:

myObject:SetPosition(123, 456)
person Michal Kottman    schedule 09.02.2011
comment
Я определенно предпочел бы числа небольшим объектам-контейнерам в Lua. Возврат вектора в Lua также возможен с помощью функций, возвращающих несколько значений. Тот факт, что функция, которая возвращает 2 значения, может быть использована в качестве аргумента в функции, которая ожидает 2 значения, делает это вдвойне полезным. - person Nick Van Brunt; 09.02.2011

В Lua Gems есть хорошая статья об оптимизации программ на Lua.

person jpjacobs    schedule 09.02.2011

Помните, Lua не знает до момента выполнения, сохранили ли вы эти объекты или нет — например, вы могли бы поместить их в таблицу в реестре. Вы даже не должны замечать последствия сбора 1,5 МБ, здесь есть еще одна проблема.

Кроме того, вы действительно тратите время на создание нового объекта для этого. Помните, что в Lua каждый объект должен размещаться динамически, поэтому вы вызываете malloc, чтобы… создать объект Vector для хранения двух чисел? Напишите свою функцию, которая принимает пару числовых аргументов в качестве перегрузки.

person Puppy    schedule 09.02.2011