释放关闭

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