javascript - "FATAL ERROR: NewSpace::Rebalance Allocation failed"但已经为垃圾收集器分配了更多空间

标签 javascript node.js out-of-memory v8 ramda.js

<--- Last few GCs --->

[19246:0x3c0ba70] 13018753 ms: Scavenge 15929.0 (32800.1) -> 17647.7 (32800.1) MB, 236071.8 / 0.0 ms  (average mu = 0.309, current mu = 0.369) allocation failure 
[19246:0x3c0ba70] 13263082 ms: Scavenge 15929.0 (32800.1) -> 17701.0 (32800.1) MB, 238469.3 / 0.0 ms  (average mu = 0.309, current mu = 0.369) allocation failure 
[19246:0x3c0ba70] 13510095 ms: Scavenge 15929.0 (32800.1) -> 17763.1 (32800.1) MB, 240951.1 / 0.0 ms  (average mu = 0.309, current mu = 0.369) allocation failure 


<--- JS stacktrace --->
Cannot get stack trace in GC.
FATAL ERROR: NewSpace::Rebalance Allocation failed - JavaScript heap out of memory
 1: 0x8dc510 node::Abort() [node]
 2: 0x8dc55c  [node]
 3: 0xad9b5e v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
 4: 0xad9d94 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
 5: 0xec7bf2  [node]
 6: 0xefaf66 v8::internal::MarkCompactCollector::Evacuate() [node]
 7: 0xefb5c2 v8::internal::MarkCompactCollector::CollectGarbage() [node]
 8: 0xed3411 v8::internal::Heap::MarkCompact() [node]
 9: 0xed3b01 v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [node]
10: 0xed4704 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
11: 0xed7371 v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [node]
12: 0xea0466 v8::internal::Factory::AllocateRawArray(int, v8::internal::PretenureFlag) [node]
13: 0xea0cea v8::internal::Factory::NewFixedArrayWithFiller(v8::internal::Heap::RootListIndex, int, v8::internal::Object*, v8::internal::PretenureFlag) [node]
14: 0xea12a7 v8::internal::Factory::NewUninitializedFixedArray(int, v8::internal::PretenureFlag) [node]
15: 0xe62190  [node]
16: 0xe65322  [node]
17: 0xe65682  [node]
18: 0xe665a2 v8::internal::ArrayConstructInitializeElements(v8::internal::Handle<v8::internal::JSArray>, v8::internal::Arguments*) [node]
19: 0x10fa09f v8::internal::Runtime_NewArray(int, v8::internal::Object**, v8::internal::Isolate*) [node]
20: 0x1bac6fc5be1d 
Aborted (core dumped)

输入将是 1028673 个 Json 对象。每个对象都包含一个名为enrollment的数组,下面的代码只会取出并处理 每个对象中的该数组。 (这里,ramda函数over()用于执行此操作)。 该字段(注册数组)的总长度为 71,157,478。

Environment: 
    NAME="Ubuntu"
    VERSION="18.04.1 LTS (Bionic Beaver)"
npm version: 6.4.1
node version: 10.15.3
run command: node --max-semi-space-size=10000 --max-old-space-size=40000 xx.js
Memory: 80G
Data size: 1028673 records (1 record ~= 4kb) (so approx. 4gib in total)

破坏程序的代码片段: 然后我对每个对象在该数组上执行了三个步骤:

  1. 为数组内的每个元素添加空字段
  2. 根据数组内元素的属性之一删除重复项。
  3. 排序
const enrollments = compose(  //ramda functions
    sortBy(prop('date')), 
    deduplicationRecord,
    map(normalizeEnrollment)
);

我已经将新空间大小和旧空间大小都设置为相对较大的空间(10g和40g)。 每个步骤只是一个函数,它将读取数组并输出一个新数组。所以我相信这里没有内存泄漏(但不确定) 我已经将新空间大小和旧空间大小都设置为相对较大的空间(10g和40g)。 如果我只执行上述三个任务,它将抛出有关垃圾收集器和内存问题的错误。然而, 如果我在排序后添加另一个 console.log() 步骤,问题将不再发生。

我的问题:

  1. 这是因为垃圾收集器没有足够的时间来收集垃圾吗? (因为当我添加 console.log() 作为最后一步时, 程序需要额外的时间在控制台中打印一些内容)
  2. 根据'Last Few GCs'的信息,它正在执行Scavenge,这是新空间的GC算法。但在错误堆栈跟踪信息中,它表示在 markcompact 期间发生了错误, 这是旧的空间GC算法。那么这个错误是发生在new space gc还是old space gc的时候呢?
  3. 对此有何潜在的优化或解决方案?

最佳答案

V8 开发人员在这里。新空间不应该(或设计)得这么大,所以我首先要尝试的是一个小得多的新空间。理想情况下,完全删除 --max-semi-space-size 标志。如果您坚持要设置它,请选择一个值,例如 8 或 16 或也许 32(可能弊大于利)。分代堆布局背后的整个想法是新空间比旧空间小得多。如果您想允许较大的堆,请增加旧空间大小,并保留新空间大小。

关于您的问题:

  1. 不,垃圾收集器将根据需要花费尽可能多的时间。我不知道为什么添加 console.log 语句在这种情况下会产生影响。
  2. 标记紧凑包括清理。失败发生在清理过程中,因为 new-space 太大。
  3. 删除 --max-semi-space-size(坚持使用默认值)应该会有所帮助。

关于javascript - "FATAL ERROR: NewSpace::Rebalance Allocation failed"但已经为垃圾收集器分配了更多空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56782874/

相关文章:

javascript - Html DOM 对象未列出属性?

javascript - Node.js - 如何找到桌面路径?

node.js - AWS Lambda : how to give ffmpeg large files?

javascript - 如何测试 Chrome 扩展?

javascript - 使用 NodeJS 使 Discord 机器人发送带有消息的图片

java - 打开 lucene 索引 : Map failed 时出错

音频缓冲区上的 java.lang.OutOfMemoryError

android - Crashlytics 报告上传因 java.lang.OutOfMemoryError 而崩溃

javascript - 在循环内的特定时间后调用函数

javascript - 使用异步函数添加到数组