释放闭包

时间:2018-04-23 20:18:43

标签: 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()
            sock:close()
        end
    end

    sock:on("sent", sendchunk)
    sendchunk()
end

传输几个文件后,解释器由于“内存不足”而发生混乱。我可以想象这可能是因为关闭仍然悬挂。垃圾收集器很难确定一旦文件和套接字关闭就不会再调用sendchunk()。

不幸的是,我的谷歌搜索没有透露一种方法来结束关闭并释放它正在使用的内存。

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

1 个答案:

答案 0 :(得分:4)

已经提到here :on()调用在Lua注册表中保存对回调闭包的引用。
我想这个闭包将从__gc sock对象的sock元方法中的Lua注册表中清除。 但如果闭包引用sock对象,则不会收集sock对象 要解决此问题,您应该避免在sendchunk()函数体中对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 upvalue的引用进行硬编码。
例如,利用传递给回调函数的第一个参数始终是套接字对象的事实。

#include <stdarg.h>

void foo(int x, ...) {
    va_list ap;
    va_start(ap, x);
    const char *optional = x ? va_arg(ap, const char *) : 0;
    va_end(ap);
    /* ... */
}