【问题标题】:Node.js Stream API leakNode.js 流 API 泄​​漏
【发布时间】:2013-12-25 06:56:28
【问题描述】:

在玩节点流时,我注意到几乎每个教程都教授以下内容:

// Get Google's home page.
require('http').get("http://www.google.com/", function(response) {
  // The callback provides the response readable stream.
  // Then, we open our output text stream.
  var outStream = require('fs').createWriteStream("out.txt");

  // Pipe the input to the output, which writes the file.
  response.pipe(outStream);
});

但在我看来,这是一段相当危险的代码。如果文件流在某个时候抛出异常会发生什么?我认为文件流可能会泄漏内存,因为根据文档,文件流显然没有关闭。

我应该关心吗?在我看来 node.js 流应该处理情况......

【问题讨论】:

    标签: node.js http asynchronous stream pipe


    【解决方案1】:

    排除 Node 的 VM 中的任何错误,如果在打开流后出现中断操作的异常,我希望最终在垃圾收集期间 VM 会检测到没有任何内容引用流并收集它,从而处理与其关联的资源。

    所以我不会称之为“泄漏”。

    仍然可能存在与处理异常或不关闭流相关的问题。例如,在 Unix 类型的系统上,当创建与磁盘上的文件相对应的流时,会使用文件描述符。一个进程一次可以打开多少个文件描述符是有限制的。因此,如果一个没有显式关闭其流的进程设法让其中许多未关闭,以至于在下一次垃圾回收之前达到文件描述符限制,它将崩溃。

    【讨论】:

    • 这基本上是我的想法。因此,如果目标流失败(例外情况),通过管道传输到目标流的源流不会关闭。
    • 它不会在异常发生时立即关闭,但垃圾收集应该到达并关闭它。
    【解决方案2】:

    为避免文件描述符泄漏,还需要:

    var outStream = require('fs').createWriteStream("out.txt");
    
    // Add this to ensure that the out.txt's file descriptor is closed in case of error.
    response.on('error', function(err) {
      outStream.end();
    });
    
    // Pipe the input to the output, which writes the file.
    response.pipe(outStream);
    

    另一个未记录的方法是outStream.destroy(),它也会关闭描述符,但似乎首选outStream.end()

    【讨论】:

      猜你喜欢
      • 2015-11-04
      • 2013-11-02
      • 2012-03-11
      • 2016-01-01
      • 2014-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多