释放关闭
Releasing closures
在 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()
sock:close()
end
end
sock:on("sent", sendchunk)
sendchunk()
end
传输几个文件后,解释器因 "not enough memory" 而崩溃。我可以想象这可能是由于关闭仍然存在。垃圾收集器很难确定文件和套接字关闭后不会再次调用 sendchunk()。
不幸的是,我的谷歌搜索没有揭示结束闭包并释放它正在使用的内存的方法。
我是不是用错了方法?我应该使用匿名函数还是什么?
已经提到 :on()
调用保存了对 Lua 注册表中回调闭包的引用。
我想这个闭包将从 sock
对象的 __gc
元方法内的 Lua 注册表中清除,
但如果闭包引用 sock
对象,则不会收集 sock
对象。
要解决这个问题,您应该避免在 sendchunk()
函数的主体中硬编码对 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
在 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()
sock:close()
end
end
sock:on("sent", sendchunk)
sendchunk()
end
传输几个文件后,解释器因 "not enough memory" 而崩溃。我可以想象这可能是由于关闭仍然存在。垃圾收集器很难确定文件和套接字关闭后不会再次调用 sendchunk()。
不幸的是,我的谷歌搜索没有揭示结束闭包并释放它正在使用的内存的方法。
我是不是用错了方法?我应该使用匿名函数还是什么?
已经提到 :on()
调用保存了对 Lua 注册表中回调闭包的引用。
我想这个闭包将从 sock
对象的 __gc
元方法内的 Lua 注册表中清除,
但如果闭包引用 sock
对象,则不会收集 sock
对象。
要解决这个问题,您应该避免在 sendchunk()
函数的主体中硬编码对 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