Node.js 流 API 泄漏
Posted
技术标签:
【中文标题】Node.js 流 API 泄漏【英文标题】:Node.js Stream API leak 【发布时间】: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 流应该处理情况......
【问题讨论】:
【参考方案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()
。
【讨论】:
以上是关于Node.js 流 API 泄漏的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 node.js 顺序读取 csv 文件(使用流 API)
在 Node.js 上从 Web Audio API 播放 PCM 流
哪些库可用于使用 WritableStream 和 Node.js Readable 等标准流 API 将数据从浏览器流式传输到服务器? [关闭]