What is causing my program to run out of memory using NodeMCU?

人盡茶涼 提交于 2019-12-12 23:23:32

问题


Can someone please tell me why my program runs out of memory? I'm using the Lua 5.1.4 on SDK 1.5.4.1 NodeMCU. Here is my code

wifi.setmode(wifi.STATION)

wifi.sta.config("asdf","xxx")

elWiFi =(wifi.sta.getip())
if elWiFi ~= nil then
    print(wifi.sta.getip())
end

if srv~=nil then
    srv:close()
end

srv=net.createServer(net.TCP) 
if srv ~= nil then
    srv:listen(6969,function(conn) 
        if conn ~= nil then
        conn:on("receive",function(sck,numbers) 
        if numbers ~= nil then 
            collectgarbage("collect")
            p = string.find(numbers, "x=") --parses TCP string
            q = string.find(numbers, "&y")
            if p ~= nill then
                if q ~=  nil then
                    x = (string.sub(numbers,p+2, q-1))
                    print("x=" .. x )       -- prints x value
                end
            end --p ~= nill
            p = string.find(numbers, "y=")
            q = string.find(numbers, "&z")
            if p ~= nil then
                if q ~=  nil then
                    y = (string.sub(numbers,p+2, q-1))
                    print("y=" .. y)          --prints y value
                end
            end --p ~= nill
            p = string.find(numbers, "z=")
            q = string.find(numbers, " H")
            if p ~= nill then
                if q ~=  nil then
                    z = (string.sub(numbers,p+2, q-1))
                    --print("z=" .. z)
                end
            end-- p ~= nill
        end --numbers ~= nil
        conn:close()
        --conn = nil

        print(collectgarbage("count")*1024)
        collectgarbage("collect")
        --print(collectgarbage("count")*1024)

        --conn:send("test\n")

        end)
        end
    end)

end

I print the Heap memory after each it parses x and y before and after collecting garbare. It increases over time and eventually crashes.

Here is what the output looks like

x=-0.003997802734375
y=-0.0095672607421875
6744
6744
x=-0.0029449462890625
y=-0.0099945068359375
7133
7098
.
.
.
x=-0.003662109375
y=-0.00982666015625
35309
35275
x=-0.00311279296875
y=-0.0097503662109375
35424
35389
E:M 64
PANIC: unprotected error in call to Lua API (not enough memory)

 ets Jan  8 2013,rst cause:2, boot mode:(3,7)

load 0x40100000, len 25936, room 16 
tail 0
chksum 0x5b
load 0x3ffe8000, len 2268, room 8 
tail 4
chksum 0xe4
load 0x3ffe88dc, len 8, room 4 
tail 4
chksum 0xd9
csum 0xd9
„ã ì ƒNì’r‚òn|ä d dld` „ãrÛ$Œ ò „  ìdà

NodeMCU custom build by frightanic.com
 branch: master
 commit: 7b83bbb2ea134cd85ac9d63108603cc02c4e20f7
 SSL: false
 modules: adc,file,gpio,net,node,ow,pwm,spi,struct,tmr,uart,websocket,wifi
 build  built on: 2016-11-15 00:43
 powered by Lua 5.1.4 on SDK 1.5.4.1(39cb9a32)
> x=-0.003997802734375

And it restarts after that.

Thanks for the help in advance.


回答1:


Within the conn:on("receive") callback you mustn't reference the conn variable but the sck variable and here's why:

The callback registered for the 'connection' event keeps a reference to conn and conn keeps reference to the callback closure. This creates a perfect a reference cycle. Because that cannot be garbage collected there's your memory leak.

Furthermore, you shouldn't close the connection within an event callback.

For more discussions see https://github.com/nodemcu/nodemcu-firmware/issues/1303 and https://stackoverflow.com/a/37379426/131929.




回答2:


This upval leak in net is a bummer. The easiest way to avoid the accidental upval binding is to hoist the declaration of the receiver routine. Something like the following. I've also recoded your parser albeit with the same syntax assumptions in more economic Lua. (Not debugged so I might have a typo, etc.)

local srv=net.createServer(net.TCP)
local function receiver(sck,numbers)
  local p={}
  for v,n in (numbers or ''):gmatch("([x-z])=(%d+)") do
    print (("%s=%s"):format(v,n))
    p[v]=n+0
  end
  -- processReq(p.x, p.y, p.z)
  print(collectgarbage("count")*1024)
  collectgarbage("collect")
  sck:close()
end

if svr then
  srv:listen(6969,function(conn) conn:on("receive",receiver) end)
end


来源:https://stackoverflow.com/questions/40748202/what-is-causing-my-program-to-run-out-of-memory-using-nodemcu

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!