Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Memory leaks 释放关闭_Memory Leaks_Lua_Closures_Nodemcu - Fatal编程技术网

Memory leaks 释放关闭

Memory leaks 释放关闭,memory-leaks,lua,closures,nodemcu,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()

在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()将不会再次被调用

不幸的是,我的谷歌搜索并没有发现一种结束闭包并释放内存的方法

我用了一个错误的方法来做这件事吗?我应该使用匿名函数还是什么?

前面已经提到,
:on()
调用会在Lua注册表中保存对回调闭包的引用。
我猜这个闭包将从
\uu gc
sock对象的metamethod中的Lua注册表中清除,
但是,如果闭包引用了
sock
对象,则不会收集
sock
对象。
要解决此问题,应避免对
sendcunk()
函数体中的
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
前面已经提到,
:on()
调用将回调闭包的引用保存在Lua注册表中。
我猜这个闭包将从
\uu gc
sock对象的metamethod中的Lua注册表中清除,
但是,如果闭包引用了
sock
对象,则不会收集
sock
对象。
要解决此问题,应避免对
sendcunk()
函数体中的
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

在运行垃圾收集器之前,您是否设置了
sendcunk=nil
?我希望垃圾收集器能够自动运行。但是,是的,我尝试在else块中设置
sendcheck=nil
。使用
collectgarbage(“count”)
我仍然可以看到每次文件传输后内存使用量都在增加。运行
collectgarbage()
似乎不会释放任何这些。在您的代码中,sendchunk是一个全局函数,因此垃圾收集器不会删除它,除非您按照lhf的建议将其设置为nil。注意,Egor在他的回答中把它放在了本地。但这并不是内存泄漏的原因,正如他解释的那样。好吧,看来collectgarbage(“计数”)并不像宣传的那样工作。在使用Egor版本的代码进行了数百次文件传输之后,它报告说Lua使用的内存总量为7485 KB,这在一个只有128 KB内存的设备上非常令人印象深刻。因此,collectgarbage(“count”)似乎不是确定内存是否泄漏的可用方法。在运行垃圾收集器之前,您是否设置了
sendcunk=nil
?我希望垃圾收集器能够自动运行。但是,是的,我尝试在else块中设置
sendcheck=nil
。使用
collectgarbage(“count”)
我仍然可以看到每次文件传输后内存使用量都在增加。运行
collectgarbage()
似乎不会释放任何这些。在您的代码中,sendchunk是一个全局函数,因此垃圾收集器不会删除它,除非您按照lhf的建议将其设置为nil。注意,Egor在他的回答中把它放在了本地。但这并不是内存泄漏的原因,正如他解释的那样。好吧,看来collectgarbage(“计数”)并不像宣传的那样工作。在使用Egor版本的代码进行了数百次文件传输之后,它报告说Lua使用的内存总量为7485 KB,这在一个只有128 KB内存的设备上非常令人印象深刻。因此,collectgarbage(“count”)似乎不是一种确定内存是否泄漏的可用方法。我使用此版本的函数进行了数百次文件传输,它仍在愉快地工作。这似乎堵住了我的记忆漏洞。谢谢。我用这个版本的函数做了几百次文件传输,现在仍然很开心。这似乎堵住了我的记忆漏洞。谢谢