Созданные экземпляры класса не освобождаются при выходе из области видимости, не могу вдуплить почему так? Стандартный Lua код, везде работает а в warcraft'e проблема.
.если заменять объявление класса на численную переменную то работает всё нормально
myClass = {}
function myClass:new( )
  local obj = {}
  obj.x = 0.0
  obj.y = 0.0
  obj.z = 0.0
  
  setmetatable(obj, self)
  self.__index = self
  return obj
end

function loop()
	for i = 1, 9000 do
		local a = myClass:new()  --- <<<<  переменная а навсегда остается в памяти
	end
end

function init()
    initTrg = CreateTrigger(  )
    TriggerRegisterTimerEventPeriodic( initTrg, 0.01 )
    TriggerAddAction( initTrg, loop )
end

  1. Есть небольшой нюанс - сборщик мусора собирает мертвые объекты когда их количество достигло критического уровня, а не когда они выходят из области видимости. Возможно, что-то мешает ему успешно собрать мусор, например создание 900 тысяч новых объектов в секунду.
  2. Попробуй нормальный таймер вместо периодик триггера, периодик триггеры известны своей лагучестью.
`
ОЖИДАНИЕ РЕКЛАМЫ...
15
А каким образом ты определил что она навсегда остается в памяти?
9
GetLocalPlayer:
А каким образом ты определил что она навсегда остается в памяти?
Цикл работает до тех пор пока варкрафт не ляжет.
24
  1. Есть небольшой нюанс - сборщик мусора собирает мертвые объекты когда их количество достигло критического уровня, а не когда они выходят из области видимости. Возможно, что-то мешает ему успешно собрать мусор, например создание 900 тысяч новых объектов в секунду.
  2. Попробуй нормальный таймер вместо периодик триггера, периодик триггеры известны своей лагучестью.
Принятый ответ
7
com23:
prog:
Спасибо работает, теперь использую TimerStart(...)
да и я теперь не буду использоваьт триггеры для таймера а просто таймер функции
9
Поторопился я немного с ответом... вообщем проблема всё еще актуальна :D
запускаю этот же код из C++, работает всё нормально
29
Мне вот интересно, обнуляется ли переменная 'a', если она локальная, может тут есть подвох, и нужно ставить после 'local a = my:Class:new()' 'a = nil'. Или не помогает обнуление a после его объявление и принятия созданного для него класса?
9
KingMaximax:
Не помогает, делал даже что-то вроде деструктора
function myClass:delete()
self.x = nil
self.y = nil
self.z = nil
end
тоже не вышло
9
Неужели нету шарящих в луа? кто то же должен знать как это побороть...
Этот комментарий удален
38
У меня память сильно не росла, когда я плодил векторы

Проверить можно в демо карте к inputMovement
24
Рекомендую засечь сколько времени занимает один запуск этого девятитысячного цикла, просто на случай если по каким-то причинам это занимает дольше чем 0.01 секунды.
Ну и да, утверждать что лаги вызваны тем что объекты остаются в памяти это бред и гадание на кофейной гуще. Делайте слабую ссылку и проверяйте после того как сработал сборщик мусора что эта ссылка перестала вести к объекту, если хотите проверить удаляются ли объекты. То что сейчас больше нельзя вызвать сборку мусора вручную, это отдельная тема...

запускаю этот же код из C++, работает всё нормально
Подробнее. Как запускаете? Где запускаете? Откуда у вас в C++ варовский таймер или периодик триггер, чтобы там можно было бы запустить именно этот код, а не похожий?
32
prog, xgm.guru/p/wc3/anyscript
Но тут важно заметить, код выполняется вне виртуальной машины.
24
quq_CCCP, если автор вопроса действительно использует этот способ - ему стоило указать это в вопросе, чтобы не создавалось впечатление будто это рефорж и близовская интеграция луа.

вне виртуальной машины.
А это что за бред? Вы там научились запускать луа без луа-машины или что?
33
quq_CCCP, Автор разумеется работает в рефордже, это же наш конкурсант с картой Фарш

И энискрипт тут вообще не причем
38
Я думаю, это цпу не успевает порешать 9000 цикл и новые вызовы ставятся в очередь. Т.е. растет очередь, а не сами объекты
9
prog:
Лаги были из-за того что память кончилась.
Дело не в таймере, пробовал и без него.
С помощью этого кода выяснилось что сборщик не успевает запуститься если плодить много объектов
и выяснилась что чем меньше объектов создаю тем чаще он вызывается
myClass = {}
function myClass:new( )
  local obj = {}
  obj.x = 0.0
  obj.y = 0.0
  obj.z = 0.0
  
  function myClass:__gc()
	if first == true then
		DisplayTimedTextToForce( GetForceOfPlayer(Player(0)), 1.1, "Destructor" )
		first = false
	end    
  end
  
  setmetatable(obj, self)
  self.__index = self
  return obj
end
first = true

function loop()
	for i = 1, 90 do
		first = true
		local a = myClass:new()  
	end
end

function init()
    initTrg = CreateTrigger(  )
    TriggerRegisterTimerEventPeriodic( initTrg, 0.01 )
    TriggerAddAction( initTrg, loop )
end
Судя из этой статьи сборщик может не успевать очищать память при маленьком множителе.
Здесь написано близзы перестали использовать стандартный сбощик и используют свой.
Запускал также из мэйна C++ с помощью LuaBridge.(работает норм)
Корень проблемы мне все еще не понятен.
Вывод который я сделал: не стоит больше заниматься такой ерундой :D
24
Видимо, близы где-то накосячили с настройками сборщика мусора - на более ранних версиях рефоржа у меня не было проблем с очисткой памяти на похожих тестах.
33
Ну мои тесты показали, что сборщик срабатывает каждые ~500 мегабайт, хз сколько объектов при этом и какой интервал... ну скажем при одинаковой динамике срабатывает примерно каждый 7-10 минут, и освобождает ~ 500 метров.
Это не сильно точно, ибо я не смотрел поведение в других картах.... и проверял я это чисто визуально, на втором мониторе открыт диспетчер задач
25
Bergi_Bear:
Ну мои тесты показали, что...
Дааа, эксперименты наше все)))
Чтобы оставить комментарий, пожалуйста, войдите на сайт.