Lua 使用gpio脉冲时存在内存泄漏问题

Lua 使用gpio脉冲时存在内存泄漏问题,lua,esp8266,nodemcu,Lua,Esp8266,Nodemcu,我使用Lua和gpio.pulse控制步进电机定时的gpio引脚 我已将问题简化为工作案例和非工作案例。如果我连续调用pulse:从同一张表开始,一切正常 如果这种情况下,连续调用需要一组不同的信息,并且对gpio.pulse.build的调用会导致内存泄漏 这很好 gpio.mode(1, gpio.OUTPUT, gpio.PULLUP) gpio.mode(7, gpio.OUTPUT, gpio.PULLUP) gpio.write(1, gpio.LOW) gpio.write(7,

我使用Lua和gpio.pulse控制步进电机定时的gpio引脚

我已将问题简化为工作案例和非工作案例。如果我连续调用pulse:从同一张表开始,一切正常

如果这种情况下,连续调用需要一组不同的信息,并且对gpio.pulse.build的调用会导致内存泄漏

这很好

gpio.mode(1, gpio.OUTPUT, gpio.PULLUP)
gpio.mode(7, gpio.OUTPUT, gpio.PULLUP)

gpio.write(1, gpio.LOW)
gpio.write(7, gpio.LOW)

local stepAction = {}
table.insert(stepAction, { [7] = gpio.LOW, delay=500 })
table.insert(stepAction, { [7] = gpio.HIGH, delay=500, loop=1, count=10})
pulsar = gpio.pulse.build(stepAction)

mytimer = tmr.create()
mytimer:alarm(100, tmr.ALARM_SEMI, function (t)
    pulsar:start(function()
        print ('done:' .. node.heap())
        mytimer:start()
    end)
end)
但这会一直泄漏到内存不足

gpio.mode(1, gpio.OUTPUT, gpio.PULLUP)
gpio.mode(7, gpio.OUTPUT, gpio.PULLUP)

gpio.write(1, gpio.LOW)
gpio.write(7, gpio.LOW)


mytimer = tmr.create()
mytimer:alarm(100, tmr.ALARM_SEMI, function (t)
    local stepAction = {}
    table.insert(stepAction, { [7] = gpio.LOW, delay=500 })
    table.insert(stepAction, { [7] = gpio.HIGH, delay=500, loop=1, count=10})
    pulsar = gpio.pulse.build(stepAction)
    stepAction = nil
    pulsar:start(function()
        print ('done:' .. node.heap())
        mytimer:start()
    end)
end)
在构建调用和调用pulsar:cancel之后,我尝试将stepAction设置为nil

node.heap多次打印相同的数字,然后在一次调用中删除5-6k,直到内存不足

还尝试设置node.egc.setmode(node.egc.ALWAYS),结果相同

Am在主版本2.2.1之外构建NodeMcu的本地版本

也曾尝试作为


local function IntervalTimerAction (timer)
    return function()
        local stepAction = {}
        table.insert(stepAction, { [7] = gpio.LOW, delay=500 })
        table.insert(stepAction, { [7] = gpio.HIGH, delay=500, loop=1, count=10})
        pulsar = gpio.pulse.build(stepAction)
        stepAction = nil
        pulsar:start(function()
            print ('done:' .. node.heap())
            timer:start()
        end)
    end
end

gpio.mode(1, gpio.OUTPUT, gpio.PULLUP)
gpio.mode(7, gpio.OUTPUT, gpio.PULLUP)

gpio.write(1, gpio.LOW)
gpio.write(7, gpio.LOW)

node.egc.setmode(node.egc.ALWAYS)
mytimer = tmr.create()
mytimer:alarm(1000, tmr.ALARM_SEMI, IntervalTimerAction(mytimer))
同样的结果

根据Egor的建议进行最终尝试

local function IntervalTimerRestart (timer)
    return function()
        print ('done:' .. node.heap())
        timer:start()
    end
end

local function IntervalTimerAction (actions, timer)
    return function()
        for id, a in next, actions do
            actions[id] = nil
        end
        table.insert(actions, { [7] = gpio.LOW, delay=500 })
        table.insert(actions, { [7] = gpio.HIGH, delay=500, loop=1, count=10})
        pulsar = gpio.pulse.build(actions)
        pulsar:start(IntervalTimerRestart (timer))
    end
end

gpio.mode(1, gpio.OUTPUT, gpio.PULLUP)
gpio.mode(7, gpio.OUTPUT, gpio.PULLUP)

gpio.write(1, gpio.LOW)
gpio.write(7, gpio.LOW)

node.egc.setmode(node.egc.ALWAYS)
local stepAction = {}
mytimer = tmr.create()
mytimer:alarm(1000, tmr.ALARM_SEMI, IntervalTimerAction(stepAction, mytimer))


相同的结果将导致一个bug,并将结果发回此处

尝试将
pulsar:start使用的回调函数移到计时器回调之外。在程序开始时定义此函数并调用
pulsar:start(my_callback)
。我认为我的编辑是您建议的,但仍然是相同的结果我的建议是避免在计时器回调中创建新的pulser回调函数。使您的程序具有唯一的脉冲回调函数。每次激活计时器回调时,编辑仍会创建新的函数实例。(为什么需要
newTimer
。确保没有禁用GC 2。确保您没有以某种方式阻止收集临时表3。手动触发垃圾收集并查看发生了什么4。看看您是否可以清除并重新使用现有的表(无论如何,这是一个很好的实践,因为它可以减少垃圾收集,这意味着更快的执行)@EgorSkriptunoff抱歉,我没有正确解释您的评论,而且我的更改在事后看来(深夜)没有多大意义。我已经改变了它的指示与相同的结果。内存在15-40次迭代中保持稳定,然后下降约5k