Lua 使用gpio脉冲时存在内存泄漏问题
我使用Lua和gpio.pulse控制步进电机定时的gpio引脚 我已将问题简化为工作案例和非工作案例。如果我连续调用pulse:从同一张表开始,一切正常 如果这种情况下,连续调用需要一组不同的信息,并且对gpio.pulse.build的调用会导致内存泄漏 这很好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,
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