我尝试创建一个 20MB 的文件,但它抛出了内存错误,将 max-old-space-size 设置为 2gb,但仍然有人可以向我解释为什么写一个 20mb 的流会消耗这么多内存?
我有 2.3 GB 的可用内存
let size=20*1024*1024; //20MB
for(let i=0;i<size;i++){
writeStream.write('A')
}
writeStream.end();
我尝试创建一个 20MB 的文件,但它抛出了内存错误,将 max-old-space-size 设置为 2gb,但仍然有人可以向我解释为什么写一个 20mb 的流会消耗这么多内存?
我有 2.3 GB 的可用内存
let size=20*1024*1024; //20MB
for(let i=0;i<size;i++){
writeStream.write('A')
}
writeStream.end();
如节点文档中所述,Writable
将数据存储在内部缓冲区中。可以缓冲的数据量取决于highWaterMark
传递给流的构造函数的选项。
只要缓冲数据的大小低于以下highWaterMark
,调用Writable.write(chunk)
就会返回true
。一旦缓冲的数据超过它指定的限制,highWaterMark
它就会返回false
。这是您应该停止写入更多数据Writable
并等待drain
表明现在可以恢复写入数据的事件的时候。
您的程序崩溃,因为即使内部缓冲区已超出,它也会继续写入highWaterMark
。
检查有关Event:'drain'
. 它包括一个示例程序。
这看起来是一个不错的用例,Readable.pipe(Writable)
您可以创建一个返回字符的生成器函数,然后Readable
使用Readable.from()
. 然后将输出通过管道Readable
传输到Writable
文件。
在这里使用管道是有益的原因是:
流 API 的一个关键目标,尤其是 stream.pipe() 方法,是将数据缓冲限制在可接受的水平,以便不同速度的源和目标不会压倒可用内存。关联
和
数据流将被自动管理,以便目标 Writable 流不会被更快的 Readable 流淹没。关联
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);