Java NodeMCU:可用堆大小下降,直到内存不足错误

Java NodeMCU:可用堆大小下降,直到内存不足错误,java,http,lua,esp8266,nodemcu,Java,Http,Lua,Esp8266,Nodemcu,我的NodeMCU遇到了一些问题,它以接入点模式运行一个简单的服务器,使用ESPlorer在LUA中编程 以下是LUA脚本: local SSID = "NodeMCU" local SSID_PASSWORD = "12345678" function connect (conn) print ("Hello connect") conn:on ("receive", function (cn, req_data) print(req_data

我的NodeMCU遇到了一些问题,它以接入点模式运行一个简单的服务器,使用ESPlorer在LUA中编程

以下是LUA脚本:

local SSID = "NodeMCU"
local SSID_PASSWORD = "12345678"

function connect (conn)
   print ("Hello connect")
   conn:on ("receive",
       function (cn, req_data)
           print(req_data)
           print("Available memory :")
           print(node.heap())
           --local query_data = get_http_req (req_data)
           local query_data = {}

           cn:send("HTTP/1.1 200 OK\n\n", 
           function()
               cn:close()
               --collectgarbage()
           end)
      end)
end

-- Configure the ESP as a station (client)
wifi.setmode (wifi.SOFTAP)

cfg={}
cfg.ssid=SSID
cfg.pwd=SSID_PASSWORD
wifi.ap.config(cfg)

cfg={}
cfg.ip="192.168.1.1";
cfg.netmask="255.255.255.0";
cfg.gateway="192.168.1.1";
wifi.ap.setip(cfg)

print("Set up UART config")
uart.setup(1, 921600, 8, uart.PARITY_NONE, uart.STOPBITS_1, 1)

-- Create the httpd server
svr = net.createServer (net.TCP, 30)

-- Server listening on port 80, call connect function if a request is received
svr:listen (80, connect)
一旦这个程序在NodeMCU上运行,我就用WiFi将我的PC连接到NodeMCU,并用以下Java代码向它发送一些http POST请求:

public void sendPost(RGBWPixel[][] LedMatrix) throws Exception {

    HttpURLConnection con = (HttpURLConnection) obj.openConnection();

    System.out.println("Sending post");
    // add reuqest header
    con.setRequestMethod("POST");
    con.setRequestProperty("matrixValues", new String(convertTo1DCharArray(LedMatrix)));
    con.setDoOutput(true);


    DataOutputStream wr = new DataOutputStream(con.getOutputStream());
    wr.flush();
    wr.close();

    con.getResponseCode();

}
obj是与NodeMCU IP地址相对应的URLconnection。 与matrixValues对应的字符串的长度始终为2050

请注意,我将LUA srcipt简化为使问题发生的最小函数。更确切地说,它发生在我有cn:send()部分时,但我不知道是否可以在不发送响应的情况下接收和处理请求,因为当我没有从Java程序运行con.getResponseCode()时,请求不会被发送。我是http的初学者,所以我还不了解所有的协议

以下是ESPlorer中NodeMCU端的输出外观:

> dofile("init.lua");
Set up UART config
> Hello connect
POST / HTTP/1.1
matrixValues: 
Available memory :
38088

Available memory :
37032
Hello connect
POST / HTTP/1.1
matrixValues: 
Available memory :
37688

Available memory :
36664
Hello connect
POST / HTTP/1.1
matrixValues: 
Available memory :
37440

Available memory :
36264
经过几十次迭代后,这种情况发生了,NodeMCU重新启动:

Hello connect
POST / HTTP/1.1
matrixValues: 
Available memory :
4680

Available memory :
3600
E:M 1584
PANIC: unprotected error in call to Lua API (init.lua:19: out of memory)

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

load 0x40100000, len 26704, room 16 
tail 0
chksum 0x0c
load 0x3ffe8000, len 2184, room 8 
tail 0
chksum 0x9a
load 0x3ffe8888, len 136, room 8 
tail 0
chksum 0x44
csum 0x44
第19行对应于cn:send()的行。 我猜我在LUA脚本中声明了一些变量、函数或回调函数时出错了,直到没有更多内存为止。。。 另外,我不明白为什么只有1个“Hello connect”就有2个对conn:on回调函数(其中打印了node.heap())的调用。这就像总是发送第二个无效http请求

非常感谢您宝贵的时间和您潜在的帮助,如果您来到这篇文章的结尾

Paul

sck:send(data,fn)
相当于
sck:send(data);sck:on(“已发送”,fn)

传递给
:on()
的闭包必须不直接引用对象()。
使用回调函数的第一个参数,而不是引用upvalue

cn:send(
“HTTP/1.1 200正常\n\n”,
函数--s在此与cn具有相同的值
s:关闭()
--收集垃圾()
结束
)
发送标题:

Connection: close

既有请求也有响应。现代http服务器和客户端应用程序的默认设置是保持活动状态。当存在此标头时,另一端将在发送所有数据后显式关闭连接。当连接关闭时,内存被释放。

为每个网络帧触发
receive
事件!因此,如果发送到设备的数据超过1460字节(源自以太网帧大小),它将触发多次。您的数据大小为2050。因此,每个
connect
事件都有两个
receive
事件。伊戈尔,你知道我们如何防止此类问题不断涌入吗?我不再数多少次我给出了或多或少相同的答案。@MarcelStör-是否可以将
luaL_unref(…cb_*\u ref)
net_delete()
移动到
net_close()
?感谢您的帮助,如果这个问题已经被回答了很多次,我很抱歉,但是当你不知道问题的确切性质时,很难找到以前的答案但是,我尝试过使用您的代码(以及简化问题的较短请求),但仍然存在内存泄漏。如果我理解得好,“conn”、“cn”和“s”在我的脚本中都指同一个对象。可能是其他级别的回调有问题吗?在我们的文档中有一个很好的例子(模板)说明了如何做到这一点。就假定的泄漏而言,我很确定这不是泄漏。即使使用原始代码,您也可以在输出中看到空闲堆不时反弹。这是GC清除死内存(例如旧套接字)。这就是为什么如果MCU必须连续快速地处理大量请求,那么内存仍然会耗尽。GC释放内存的速度不够快。