使用timer.performWithDelay导致内存泄漏

时间:2012-11-18 16:15:03

标签: memory-leaks corona

我不确定为什么以下示例代码不会释放所有计时器内存。它从大约133kb开始,如果你点击它创建10,000个计时器的屏幕。他们跑完后,应该清理干净。但是在删除所有计时器之后,它的平均值大约为389kb。

我错过了什么吗?

local timersFired = 0
local timers = {}
local maxTimers = 10000

Runtime:addEventListener("touch", function(e)
    if(e.phase == "began") then
        print("TIMERS CREATED")
        timers = {}
        for i=1,maxTimers do
            table.insert(timers, timer.performWithDelay(3000, function(e)
                timersFired = timersFired + 1
            end, 1))
        end
    end
end)

Runtime:addEventListener("enterFrame", function(e)
    if(timersFired == maxTimers) then
        print("KILLED TIMERS")
        for i=1,maxTimers do
            local aTimer = timers[i]
            timer.cancel(aTimer)
            timers[i] = nil
        end

        timers = nil
        timersFired = 0
    end

    collectgarbage("collect")
    print( "MemUsage: " .. collectgarbage("count") )
end)

1 个答案:

答案 0 :(得分:0)

也许不是你唯一的问题,但删除定时器的for循环只能删除其中的一半。

循环从1 to #timers开始。第一次通过时,i为1,它将删除第一个计时器。第二次,i增加到2,但是数组中的元素在此期间向下移动,因此代码跳过计时器#2,并继续删除最初的计时器#3。等等。

最终结果是你只从定时器数组中的奇数位置移除定时器,剩下一半仍然占用内存。

while (#timers > 0) do循环可以更好地工作,或者for i = #timers, 1, -1 do循环每次都删除最后一个计时器。

您可以通过仅创建10个计时器来验证这是否是问题的一部分。打印“创建”为每个创建的,并在每个被销毁时打印“已删除”。你应该看到10个创建和10个删除。 (我想你只会看到5个删除。)