Node.js 流管道和垃圾收集

Nat*_*ebe 5 garbage-collection pipe stream node.js

问题: 在 Node.js 中,如果将可读流通过管道传输到可写流,并且两者都超出范围,则这对流是否会在读取器完成之前被垃圾收集?(因为它们现在无法访问)

背景: 我试图了解管道对流对象生命周期的影响。我的操作假设管道代表两个流之间的双向引用,因此如果一个流可访问,则两个流都不会被垃圾收集(当然,直到读取器结束并且管道关闭)。

因此,有了这样的假设:运行时中是否有任何东西可以在管道处于活动状态时或在 Readable 上的“数据”侦听器执行等效操作时保持流的存在?(除了明显的,例如事件侦听器函数和其他对象中嵌入的引用)

一个具体的例子是将文件读取流传输到 http 响应对象。如果我“管道后忘记”,并且不保留对文件或响应流的引用,那么此过程是否容易在中途中断?

或者,如果某些东西阻碍了管道流的 GC,那么两个套接字之间的双向管道是否会无限期地存在,即使它们都无法访问?(并且完全无法关闭?)

cdh*_*wie 3

与往常一样,答案是:这取决于情况。

如果没有任何内容引用流对象,那么它们将被垃圾收集。但是,除了代码之外,其他地方可能还有引用。

请注意,可读流通过事件处理程序引用可写流,因此我们真正需要的是对可读流的引用以使两者保持活动状态。

如果源是一个能够自行生成数据的流(它从文件、网络或内存中的某些内容读取)并且管道正在流动,那么它将某处的回调引用(I/O延续、事件处理程序或给setTimeout()或 的闭包process.nextTick())。

如果源是一个正在等待您将数据推入其中的流,或者管道已暂停,则可能没有引用,并且两个流最终都将被垃圾收集。