Финализаторы с __gc
Регистрируйте метаметоды __gc для очистки при сборе объектов.
«Финализаторы с __gc» — бесплатный урок Lua Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Lua Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Lua Academy содержит 4 уроков всего.
Что такое финализатор?
Финализатор — это функция, вызываемая сборщиком мусора непосредственно перед освобождением объекта. В Lua он реализуется с помощью метаметода __gc в метатаблице таблицы.
Установка финализатора
Добавьте функцию __gc в метатаблицу до создания объекта или во время его создания.
local mt = {
__gc = function(self)
print("Finalizing:", self.name)
end
}
do
local obj = setmetatable({name = "resource"}, mt)
end
collectgarbage() -- prints: Finalizing: resourceШаблон очистки ресурсов
Финализаторы идеально подходят для освобождения внешних ресурсов: дескрипторов файлов, соединений с базой данных или памяти C.
local function openResource(path)
local f = io.open(path, "r")
return setmetatable({handle = f, path = path}, {
__gc = function(self)
if self.handle then
self.handle:close()
print("Closed:", self.path)
end
end
})
endПорядок работы финализаторов
Объекты с финализаторами удаляются в обратном порядке создания. По умолчанию за один цикл сборки мусора выполняется один финализатор.
Воскрешение
Если финализатор сохраняет ссылку на объект (в глобальной переменной или внешней локальной переменной), объект воскресает. При окончательном удалении для него будет выполнен ещё только один вызов финализатора.
Пользовательские данные и __gc
В расширениях на C метаметод __gc для пользовательских данных — основной способ освободить память C. В чистом Lua таблицы используют тот же механизм через метатаблицы.
Объекты-прокси для RAII
Создайте таблицу-прокси, чей __gc закрывает настоящий ресурс. Это имитирует RAII из C++.
local function scoped(resource, cleanup)
return setmetatable({resource}, {
__gc = function(self) cleanup(self[1]) end
})
endОграничения финализаторов
Финализаторы не должны: вызывать операции сопрограмм, приостанавливаться или предполагать какой-либо порядок существования других объектов. Делайте их простыми и короткими.
Слабые таблицы и финализаторы
Объекты в слабых таблицах всё равно могут быть финализированы. После финализации (и возможного воскрешения) они полностью удаляются во время следующего цикла.
Защита финализатора toLua
Используйте внутри финализатора логический флаг, чтобы предотвратить повторную очистку в случае воскрешения объекта.
local mt = {}
mt.__gc = function(self)
if not self._closed then
self._closed = true
-- cleanup...
end
endПрактические рекомендации
Для детерминированной очистки предпочитайте явные методы :close() или :destroy(). Используйте __gc как страховку от случайно пропущенной очистки, а не как основной способ управления ресурсами.
Вопрос о финализаторах
Когда вызывается метаметод __gc?
Итоги: финализаторы с __gc
Метаметод __gc выполняется непосредственно перед удалением объекта, обеспечивая очистку ресурсов в стиле RAII. Используйте его как страховку; для детерминированного управления ресурсами предпочитайте явные методы закрытия и уничтожения.
Часто задаваемые вопросы
Урок «Финализаторы с __gc» бесплатный?
Да — полный текст урока «Финализаторы с __gc» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.
Чему я научусь в уроке «Финализаторы с __gc»?
Регистрируйте метаметоды __gc для очистки при сборе объектов. Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Lua Academy?
Предыдущий опыт не требуется. Lua Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Финализаторы с __gc»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Lua Academy?
Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Основы сборщика мусора Lua
- Слабые ключи и слабые значения
- Финализаторы с __gc
- Предотвращение утечек памяти