在阅读Github上的一些代码后,似乎我误解了这个highWaterMark概念是如何工作的.
在可写流的情况下,尽可能快地写入大量数据,这是我对生命周期的想法:
1)虽然highWaterMark未达到限制,但流能够缓冲和写入数据.
2)如果highWaterMark达到限制,则流不能再缓冲,因此#write方法返回false以告知您尝试写入的内容将不会写入(从不).
3)一旦流发出drain事件,这意味着缓冲区已被清理,您可以从"被拒绝"的位置再次写入.
在我看来这很清楚也很简单,但看起来这并不完全正确(在第2步),当#write方法返回false时,你尝试编写的数据真的被"拒绝"吗?或者是缓冲(或其他)?
对不起基本问题,但我需要确定!
Mat*_*son 17
2)如果达到highWaterMark限制,流不能再缓冲,所以#write方法返回false,让你知道你试写的东西不会写(从不).
这是错误的,数据仍然是缓冲的,流不会丢失它.但是你应该停止写作.这是为了允许背压传播.
您的问题在writable.write(chunk[, encoding][, callback])文档中得到解决:
这个返回值是严格的建议.你可以继续写,即使它返回
false.但是,写入将缓冲在内存中,因此最好不要过度执行此操作.相反,'drain'在写入更多数据之前等待 事件.
Tac*_*tex 15
当#write方法返回false时,您尝试写入的数据是否真的"被拒绝"?或者是缓冲(或其他)?
数据被缓冲.但是,write()在不允许缓冲区耗尽的情况下进行过多调用将导致高内存使用率,糟糕的垃圾收集器性能,甚至可能导致Node.js因Allocation failed - JavaScript heap out of memory错误而崩溃.看到这个相关的问题:
作为参考,以下是highWaterMark当前文档(v8.4.0)的一些相关详细信息和背压:
writable.write()
true如果内部缓冲区小于highWaterMark在录入后创建流时配置的内部缓冲区,则返回值chunk.如果false返回,则应该停止进一步尝试将数据写入流中,直到'drain'发出该事件.当流没有耗尽时,调用
write()将缓冲chunk并返回false.一旦所有当前缓冲的块被耗尽(接受由操作系统传递),'drain'将发出该事件.据建议,一旦write()返回false,没有更多的块写入,直到'drain'事件被发出.在write()允许调用未耗尽的流时,Node.js将缓冲所有写入的块,直到最大内存使用量发生,此时它将无条件地中止.即使在它中止之前,高内存使用将导致糟糕的垃圾收集器性能和高RSS(即使在不再需要内存之后,通常也不会将其释放回系统).
在数据缓冲区已超过
highWaterMark或写入队列当前正忙的任何情况下,.write()将返回false.当
false返回一个值时,背压系统启动.它将暂停传入的Readable流发送任何数据并等待消费者再次准备就绪.清空数据缓冲区后,.drain()将发出一个事件并恢复传入的数据流.队列完成后,背压将允许再次发送数据.正在使用的内存空间将自行释放并为下一批数据做好准备.
+-------------------+ +=================+
| Writable Stream +---------> .write(chunk) |
+-------------------+ +=======+=========+
|
+------------------v---------+
+-> if (!chunk) | Is this chunk too big? |
| emit .end(); | Is the queue busy? |
+-> else +-------+----------------+---+
| emit .write(); | |
^ +--v---+ +---v---+
^-----------------------------------< No | | Yes |
+------+ +---v---+
|
emit .pause(); +=================+ |
^-----------------------+ return false; <-----+---+
+=================+ |
|
when queue is empty +============+ |
^-----------------------< Buffering | |
| |============| |
+> emit .drain(); | ^Buffer^ | |
+> emit .resume(); +------------+ |
| ^Buffer^ | |
+------------+ add chunk to queue |
| <---^---------------------<
+============+
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6872 次 |
| 最近记录: |