Memory leaks 释放关闭
在nodemcu上,我使用闭包通过套接字发送文件,如下所示:Memory leaks 释放关闭,memory-leaks,lua,closures,nodemcu,Memory Leaks,Lua,Closures,Nodemcu,在nodemcu上,我使用闭包通过套接字发送文件,如下所示: function sendfile(sock, name) local fd = file.open(name, "r") function sendchunk() local data = fd:read() if data then sock:send(data) else fd:close()
function sendfile(sock, name)
local fd = file.open(name, "r")
function sendchunk()
local data = fd:read()
if data then
sock:send(data)
else
fd:close()
sock:close()
end
end
sock:on("sent", sendchunk)
sendchunk()
end
在传输了一些文件后,解释器由于“内存不足”而惊慌失措。我可以想象这可能是由于关闭仍然徘徊。垃圾收集器很难确定一旦文件和套接字关闭,sendchunk()将不会再次被调用
不幸的是,我的谷歌搜索并没有发现一种结束闭包并释放内存的方法
我用了一个错误的方法来做这件事吗?我应该使用匿名函数还是什么?前面已经提到,:on()
调用会在Lua注册表中保存对回调闭包的引用。我猜这个闭包将从
\uu gc
sock对象的metamethod中的Lua注册表中清除,但是,如果闭包引用了
sock
对象,则不会收集sock
对象。要解决此问题,应避免对
sendcunk()
函数体中的sock
upvalue引用进行硬编码。例如,利用传递给回调函数的第一个参数始终是套接字对象这一事实
function sendfile(sock, name)
local fd = file.open(name, "r")
local function sendchunk(sck)
local data = fd:read()
if data then
sck:send(data)
else
fd:close()
sck:close()
end
end
sock:on("sent", sendchunk)
sendchunk(sock)
end
前面已经提到,:on()
调用将回调闭包的引用保存在Lua注册表中。我猜这个闭包将从
\uu gc
sock对象的metamethod中的Lua注册表中清除,但是,如果闭包引用了
sock
对象,则不会收集sock
对象。要解决此问题,应避免对
sendcunk()
函数体中的sock
upvalue引用进行硬编码。例如,利用传递给回调函数的第一个参数始终是套接字对象这一事实
function sendfile(sock, name)
local fd = file.open(name, "r")
local function sendchunk(sck)
local data = fd:read()
if data then
sck:send(data)
else
fd:close()
sck:close()
end
end
sock:on("sent", sendchunk)
sendchunk(sock)
end
在运行垃圾收集器之前,您是否设置了
sendcunk=nil
?我希望垃圾收集器能够自动运行。但是,是的,我尝试在else块中设置sendcheck=nil
。使用collectgarbage(“count”)
我仍然可以看到每次文件传输后内存使用量都在增加。运行collectgarbage()
似乎不会释放任何这些。在您的代码中,sendchunk是一个全局函数,因此垃圾收集器不会删除它,除非您按照lhf的建议将其设置为nil。注意,Egor在他的回答中把它放在了本地。但这并不是内存泄漏的原因,正如他解释的那样。好吧,看来collectgarbage(“计数”)并不像宣传的那样工作。在使用Egor版本的代码进行了数百次文件传输之后,它报告说Lua使用的内存总量为7485 KB,这在一个只有128 KB内存的设备上非常令人印象深刻。因此,collectgarbage(“count”)似乎不是确定内存是否泄漏的可用方法。在运行垃圾收集器之前,您是否设置了sendcunk=nil
?我希望垃圾收集器能够自动运行。但是,是的,我尝试在else块中设置sendcheck=nil
。使用collectgarbage(“count”)
我仍然可以看到每次文件传输后内存使用量都在增加。运行collectgarbage()
似乎不会释放任何这些。在您的代码中,sendchunk是一个全局函数,因此垃圾收集器不会删除它,除非您按照lhf的建议将其设置为nil。注意,Egor在他的回答中把它放在了本地。但这并不是内存泄漏的原因,正如他解释的那样。好吧,看来collectgarbage(“计数”)并不像宣传的那样工作。在使用Egor版本的代码进行了数百次文件传输之后,它报告说Lua使用的内存总量为7485 KB,这在一个只有128 KB内存的设备上非常令人印象深刻。因此,collectgarbage(“count”)似乎不是一种确定内存是否泄漏的可用方法。我使用此版本的函数进行了数百次文件传输,它仍在愉快地工作。这似乎堵住了我的记忆漏洞。谢谢。我用这个版本的函数做了几百次文件传输,现在仍然很开心。这似乎堵住了我的记忆漏洞。谢谢