释放关闭 [英] Releasing closures

查看:89
本文介绍了释放关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在nodemcu上,我正在使用闭包通过套接字发送文件,如下所示:

On a nodemcu, I'm using a closure to send a file over a socket, like this:

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

在传输了几个文件之后,由于内存不足,解释器会出现紧急情况。我可以想象这可能是由于关闭仍然徘徊。

After transferring a few files, the interpreter panics due to "not enough memory". I can imagine this may be due to closure still hanging around. It would be difficult for the garbage collector to determine that sendchunk() will not be called again once the file and socket are closed.

不幸的是,我的谷歌搜索没有揭示一种方法,垃圾收集器很难确定一旦关闭文件和套接字,就不会再次调用sendchunk()。结束关闭并释放它正在使用的内存。

Unfortunately my googling has not revealed a method to end the closure and free the memory it is using.

我使用错误的方法来执行此操作吗?我应该使用匿名函数还是什么?

Am I using a wrong method to do this? Should I perhaps use an anonymous function or something?

推荐答案

已经提到了此处,其中:on()调用保存了Lua注册表中对回调关闭的引用。

我猜测此关闭将从Lua注册表中的 sock 对象

sock 元方法中清除。如果闭包引用 sock 对象,则不会收集 sock 对象。

解决此问题您应该避免在 sendchunk()函数的主体中对 sock 高值的引用进行硬编码。

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

It was already mentioned here that :on() invocation saves reference to callback closure inside Lua registry.
I guess this closure will be cleared from Lua registry inside __gc metamethod of sock object,
but sock object will not be collected if the closure references sock object.
To solve this problem you should avoid hard-coding a reference to sock upvalue in the body of sendchunk() function.
For example, exploit the fact that the first argument passed to callback function is always the socket object.

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

这篇关于释放关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆