Почему Lua использует сборщик мусора вместо подсчета ссылок? - PullRequest
16 голосов
/ 16 февраля 2011

Я слышал и испытал это сам: сборщик мусора Lua может вызвать серьезные падения FPS в играх по мере роста их скриптовой части.

Это, как я выяснил, связано с сборщиком мусора, где, например, каждыйСозданный объект пользовательских данных Vector () временно находится до момента сбора мусора.

Я знаю, что Python использует подсчет ссылок, и поэтому ему не требуются огромные, производительные шаги, как это делает Luas GC.

  • Почему Lua не использует подсчет ссылок, чтобы избавиться от мусора?

Ответы [ 8 ]

16 голосов
/ 16 февраля 2011

Поскольку сборщики мусора при подсчете ссылок могут легко утекать объекты.

Тривиальный пример: двусвязный список.Каждый узел имеет указатель на следующий узел - и сам указывает на следующий.Если вы просто не ссылаетесь на сам список и ожидаете, что он будет собран, вы просто слили весь список - нет узлов имеют счетчик ссылок, равный нулю, и, следовательно, все они будут поддерживать друг друга живыми,С помощью сборщика мусора, подсчитывающего ссылки, каждый раз, когда у вас есть циклический объект, вам, в основном, нужно обрабатывать его как неуправляемый объект и явно избавляться от него самостоятельно, когда вы закончите.

Обратите внимание, что Python использует правильный мусорколлектор в дополнение к подсчету ссылок.

10 голосов
/ 16 февраля 2011

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

Lua 5.1 Руководство по сбору мусора

6 голосов
/ 16 февраля 2011

Какая версия Lua используется в играх, на которых вы основываете это требование?Когда World of Warcraft переключился с Lua 5.0 на 5.1, все проблемы с производительностью, вызванные сборкой мусора, были значительно уменьшены.

При сборке мусора в Lua 5.0 количество времени, потраченное на сбор мусора (и блокирование чего-либо еще отпроисходило одновременно) и было пропорционально количеству используемой в данный момент памяти, что привело к огромным усилиям по минимизации использования памяти аддонами WoW.

При сборке мусора в Lua 5.1 сборщик изменился наинкрементный, поэтому он не блокирует игру, собирая мусор, как это было раньше.Теперь сборка мусора оказывает минимальное влияние на производительность по сравнению с большей проблемой ужасно неэффективного кода в большинстве пользовательских аддонов.

5 голосов
/ 16 февраля 2011

Одного подсчета ссылок недостаточно для корректной работы сборщика мусора, поскольку он не обнаруживает циклы.Даже Python не использует подсчет ссылок в одиночку.

Представьте, что объекты A и B содержат ссылку друг на друга.Даже если вы, программист, больше не держите ссылку на какой-либо объект, подсчет ссылок все равно скажет, что на объекты A и B есть ссылки, указывающие на них.

Существует множество различных схем сбора мусора, и некоторые будут работатьлучше в некоторых обстоятельствах, а некоторые будут работать лучше в других обстоятельствах.Дизайнеры языка должны попытаться выбрать сборщик мусора, который, по их мнению, лучше всего подойдет для их языка.

3 голосов
/ 16 февраля 2011

В общем, подсчет ссылок не является точной заменой сборки мусора из-за возможности циклических ссылок.Возможно, вы захотите прочитать на этой странице , почему сборка мусора предпочтительнее подсчета ссылок.

2 голосов
/ 15 августа 2012

Взгляните на некоторые источники CPython.Хорошая часть кода C составляет Py_DECREF и Py_INCREF.Эта мерзкая, утомительная и подверженная ошибкам бухгалтерия просто исчезает в Lua.

При необходимости ничто не мешает вам писать модули Lua на C, которые управляют любыми тяжелыми частными выделениями вручную.

2 голосов
/ 16 февраля 2011

Вас также может заинтересовать Lua Gem об оптимизации , в котором также есть часть, которая занимается сборкой мусора.

1 голос
/ 24 октября 2015

Это компромисс. Люди объяснили некоторые причины, по которым некоторые языки (это на самом деле не имеет ничего общего с Lua) используют коллекторы, но не коснулись недостатков.

Некоторые языки, в частности ObjC, используют исключительно подсчет ссылок. Огромным преимуществом этого является то, что освобождение является детерминированным - как только вы отпустите последнюю ссылку, гарантируется, что объект будет немедленно освобожден. Это важно, когда у вас есть ограничения памяти. С помощью распределителя Lua, если ограничения памяти требуют предсказуемого освобождения, вы должны добавить методы для немедленного освобождения основного хранилища, что лишает смысла сбор мусора.

«WuHoUnited» ошибочно говорит, что вы не можете этого сделать - он очень хорошо работает с ObjC на iOS и с shared_ptr в C ++. Вам просто нужно понять среду, в которой вы находитесь, чтобы избежать циклов или прервать их при необходимости.

...