Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #64, МАРТ 2006 г.

рецепты lua

АЛЕКСАНДР ГЛАДЫШ

Спецвыпуск: Хакер, номер #064, стр. 064-042-6


управление памятью

Язык Lua автоматически управляет памятью при помощи сборщика мусора (garbage collector): интерпретатор периодически вызывает сборщик мусора, удаляющий объекты, для которых была выделена память (таблицы, userdata, функции, потоки и строки) и которые стали недоступными из Lua («мертвые» объекты).

Интерпретатор Lua задает предел объема памяти (threshold), занимаемого данными. Как только занятый объем достигнет этого предела, запускается алгоритм, освобождающий память, занятую накопившимися «мертвыми» объектами. Затем устанавливается новый предел, равный двухкратному объему памяти, занимаемой после очистки.

Чтобы запустить сборку мусора немедленно, нужно программно установить предел занимаемой памяти в 0 (вызвав lua_setgcthreshold() из C или collectgar-bage() из Lua). Чтобы остановить сборку мусора, устанавливаем этот предел в достаточно большое значение.

Замечено, что в некоторых случаях память, занимаемая данными Lua, проявляет тенденцию к разрастанию, что может негативно сказаться на производительности программы. Чтобы избежать этого, лучше периодически вызывать сборку мусора принудительно.

При написании программ на Lua обязательно учитывай то, каким образом интерпретатор Lua управляет распределением памяти. Сборка мусора в версии 5.0.2 — относительно затратная по производительности операция (используется алгоритм non-incremental mark and sweep). Она инициируется автоматически, когда объем выделенной памяти превышает двукратный объем памяти, оставшейся выделенной после предыдущей сборки мусора (объем выделенной памяти, при превышении которого произойдет следующая сборка мусора, также можно задавать программно). Значит, фактически, в достаточно большой динамической системе сборка мусора может быть запущена в произвольный момент времени, вызвав просадку по производительности. Чем больше памяти выделено под объекты Lua, тем дольше происходит сбор мусора.

Итак, если ты, например, читаешь в Lua данные из файла построчно и склеиваешь их в одну строку линейно, скорее всего, процесс будет продвигаться страшно медленно: после каждой следующей операции склейки объем занятой памяти, как минимум, удваивается и, соответственно, запускается процесс сборки мусора.

Код создает новую строку (и присваивает ее переменной some_string), а строка, хранившаяся в some_string до склейки, остается в памяти до следующей сборки мусора:

some_string = some_string .. "a"

Такая проблема и способы ее решения описаны в статье Роберто Иеруса-лимского Lua Technical Note 9: Creating Strings Piece by Piece (www.lua.org/notes/ltn009.html). В Lua 5.1 реализована инкрементальная сборка мусора, позволяющая распределить нагрузку по производительности от процесса сборки мусора во времени

Сборка версии 5.0.2

LUA C API ВЕРСИИ 5.0.2 ПО УМОЛЧАНИЮ СОСТОИТ ИЗ ДВУХ СТАТИЧЕСКИХ БИБЛИОТЕК: ЯДРА И НАБОРА СТАНДАРТНЫХ БИБЛИОТЕК ЯЗЫКА (В ВЕРСИИ 5.1 ЭТИ БИБЛИОТЕКИ УЖЕ ОБЪЕДИНЕНЫ В ОДНУ). ДИСТРИБУТИВ LUA НАХОДИТСЯ НА ОФИЦИАЛЬНОМ САЙТЕ ЯЗЫКА — www.lua.org. МОЖЕШЬ СКАЧАТЬ ПРЕКОМПИЛИРОВАННУЮ ВЕРСИЮ LUA С САЙТА LUAFORGE (luabinaries.luaforge.net).

Назад на стр. 064-042-5  Содержание  Вперед на стр. 064-042-7