【问题标题】:WriteStream nodejs out memoryWriteStream nodejs出内存
【发布时间】:2021-02-11 14:11:42
【问题描述】:

我尝试创建一个 20MB 的文件,但它抛出了内存不足的错误,将 max-old-space-size 设置为 2gb,但仍然有人可以向我解释为什么写一个 20mb 的流会消耗这么多内存?

我有 2.3 g.b 的可用内存

let size=20*1024*1024; //20MB

for(let i=0;i<size;i++){
     writeStream.write('A')
}
writeStream.end();

【问题讨论】:

    标签: node.js stream createwritestream


    【解决方案1】:

    如node documentation 中所述,Writable 将数据存储在内部缓冲区中。可以缓冲的数据量取决于传递给流的构造函数的highWaterMark 选项。

    只要缓冲数据的大小低于highWaterMark,对Writable.write(chunk) 的调用将返回true。一旦缓冲的数据超过highWaterMark 指定的限制,它就会返回false。此时您应该停止向Writable 写入更多数据并等待drain 事件,这表明现在可以继续写入数据了。

    您的程序崩溃了,因为即使内部缓冲区已超过highWaterMark,它仍在继续写入。

    查看有关Event:'drain' 的文档。它包括一个示例程序。


    这看起来是 Readable.pipe(Writable) 的一个不错的用例 您可以创建一个返回字符的生成器函数,然后使用Readable.from() 从该生成器创建一个Readable。然后将Readable 的输出通过管道传输到Writable 文件。

    这里使用管道的好处是:

    流 API 的一个关键目标,尤其是 stream.pipe() 方法, 是将数据的缓冲限制在可接受的水平,使得 不同速度的来源和目的地不会压倒 有效内存。 link

    和

    数据流将被自动管理,以便目的地 可写流不会被更快的可读流淹没。 link

    const { Readable } = require('stream');
    const fs = require('fs');
    
    const size = 20 * 1024 * 1024; //20MB
    
    function * generator(numberOfChars) {
        while(numberOfChars--) {
            yield 'A';
        }
    }
    
    const writeStream = fs.createWriteStream('./output.txt');
    const readable = Readable.from(generator(size));
    
    readable.pipe(writeStream);
    

    【讨论】:

    • 它对我来说非常有效,我的问题只是因为第一种方法失败了,在他们推荐使用 stream.once ('Drain') 的文档中,我看到了异步发送数据也可以,
    • @KevinMendoza,我刚刚编辑了答案以解释您的程序失败的原因。
    • 简而言之,数据在缓冲区中写入速度更快,它能够清空什么?这就是它失败的原因。
    • @KevinMendoza,当您将数据从一个流传输到另一个流时,如果发送者比接收者快,则发送的数据必须临时存储在某个地方。这个临时存储是缓冲区。所以我不认为这是为了加快进程,而是为了同步不同带宽的发送者和接收者。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-15
    • 1970-01-01
    • 2016-06-04
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 2013-11-02
    相关资源
    最近更新 更多