释放闭包

在 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

传输几个文件后,解释器出现"内存不足"错误。我能想象到这可能是因为闭包仍然存在。垃圾收集器很难确定一旦文件和套接字关闭,sendchunk() 将不会再被调用。

不幸的是,我查找了很多却没有发现一种方法来结束闭包并释放它所使用的内存。

我使用了错误的方法吗?也许我应该使用匿名函数或其他方法吗?

点赞
用户1847592
用户1847592

已经在这里提到,:on()调用会保存回调闭包的引用到Lua注册表中。

我猜测这个闭包将在sck对象的 __gc元方法中从Lua注册表中清除,但如果闭包引用了sck对象,则sck对象将不会被收集。

为了解决这个问题,你应该避免在sendchunk()函数的主体中硬编码对sck闭包的引用。

例如,利用回调函数传递的第一个参数始终是套接字对象的事实。

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
2018-04-23 23:34:56