簡體   English   中英

使用 node.js 中的 createWriteStream 創建大文件時 JavaScript 堆內存不足 致命錯誤:達到堆限制分配失敗

[英]JavaScript heap out of memory while creating a huge file using createWriteStream in node.js FATAL ERROR: Reached heap limit Allocation failed

const fs = require('fs');
const file = fs.createWriteStream('./big.file');


for(let i=0; i<1e8; i++){
    file.write(`llorem ipsum ${i}`);
}

file.end();

上面的代碼嘗試使用fs.createWriteStream在 node.js 中創建一個巨大的文件,據我所知,流是可能無法立即使用且不必放入內存的數據集合。 但是當我運行我的腳本時,我的內存占用不斷增加,最終導致 JavaScript 堆內存不足錯誤。 我的問題是我是否遺漏了關於流的任何信息,以及如果流不需要適合內存,為什么會發生這種情況。

腳本運行前腳本運行前

腳本運行后在此處輸入圖片說明

錯誤

<--- Last few GCs --->

[386723:0x6297e70]    42815 ms: Mark-sweep (reduce) 2046.9 (2081.1) -> 2046.2 (2081.6) MB, 1806.1 / 0.0 ms  (+ 94.3 ms in 13 steps since start of marking, biggest step 7.6 ms, walltime since start of marking 1911 ms) (average mu = 0.341, current mu = 0.10[386723:0x6297e70]    45153 ms: Mark-sweep (reduce) 2047.7 (2081.8) -> 2046.9 (2082.1) MB, 1919.1 / 0.0 ms  (+ 123.1 ms in 16 steps since start of marking, biggest step 11.3 ms, walltime since start of marking 2057 ms) (average mu = 0.244, current mu = 0.

<--- JS stacktrace --->

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
 1: 0xb17ec0 node::Abort() [node]
 2: 0xa341f4 node::FatalError(char const*, char const*) [node]
 3: 0xcfe71e v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
 4: 0xcfea97 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
 5: 0xee8d35  [node]
 6: 0xef7ab1 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
 7: 0xefad0c v8::internal::Heap::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [node]
 8: 0xec72bb v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationType, v8::internal::AllocationOrigin) [node]
 9: 0x123052b v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*, v8::internal::Isolate*) [node]
10: 0x16147d9  [node]
Aborted (core dumped)

我相信您需要檢查write()的返回值,當它為false時停止寫入,並利用drain事件指示何時再次開始寫入。

目前您的循環只是無限期地寫入內部緩沖區而不刷新到磁盤,這就是您的腳本導致內存錯誤的原因。

這樣的事情應該工作:

const fs = require('fs');
const file = fs.createWriteStream('./big.file');

const max = 1e8;
let i = 0;

file.on('drain', function writeAsMuchAsPossible() {
  while (i < max && file.write(`llorem ipsum ${i++}`));
  if (i === max) {
    file.end();
  }
}).emit('drain')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM