I got the following error while I implemented D way heap.
<--- Last few GCs ---> [9128:00000252D029E130] 6378 ms: Scavenge 925.0 (942.3) -> 909.0 (942.3) MB, 0.3 / 0.0 ms (average mu = 0.796, current mu = 0.722) allocation failure [9128:00000252D029E130] 6388 ms: Scavenge 925.0 (942.3) -> 909.0 (942.3) MB, 0.2 / 0.0 ms (average mu = 0.796, current mu = 0.722) allocation failure [9128:00000252D029E130] 6398 ms: Scavenge 925.0 (942.3) -> 909.0 (942.3) MB, 0.2 / 0.0 ms (average mu = 0.796, current mu = 0.722) allocation failure <--- JS stacktrace ---> FATAL ERROR: invalid array length Allocation failed - JavaScript heap out of memory 1: 00007FF7B4DD176F napi_wrap+109135 2: 00007FF7B4D76AD6 v8::internal::OrderedHashTable<v8::internal::OrderedHashSet,1>::NumberOfElementsOffset+33350 3: 00007FF7B4D778A6 v8::internal::OrderedHashTable<v8::internal::OrderedHashSet,1>::NumberOfElementsOffset+36886 4: 00007FF7B5645DFE v8::Isolate::ReportExternalAllocationLimitReached+94 5: 00007FF7B562AC4D v8::SharedArrayBuffer::Externalize+781 6: 00007FF7B54D508C v8::internal::Heap::EphemeronKeyWriteBarrierFromCode+1516 7: 00007FF7B54F9DCF v8::internal::Factory::NewUninitializedFixedArray+111 8: 00007FF7B53BE160 v8::Message::GetIsolate+8128 9: 00007FF7B5247437 v8::internal::interpreter::JumpTableTargetOffsets::iterator::operator=+170247 10: 00007FF7B56CE94D v8::internal::SetupIsolateDelegate::SetupHeap+463949 11: 0000035EFA6C37E4
Let’s check the following example.
const map = new Map<number, number[]>();
const array = [2, 1];
map.set(1, array);
for (const value of array) {
const currentValue = map.get(1);
if (currentValue) {
currentValue.push(array.length + 1);
map.set(1, currentValue);
}
}
This code doesn’t break the for-loop. array
is defined on the 2nd line and it’s specified to the map. When map.get(1)
is called, the same object is returned. What happens when a new value is added to the array? Yes, the length increases. Therefore, the total loop count increases too.
It becomes like this in the loop.
for (const value of [2, 1])
--> for (const value of [2, 1, 3])
--> for (const value of [2, 1, 3, 4])
--> ...
We somehow need to avoid this infinite loop.
The solution is easy. Use the copy of the array instead.
const map = new Map<number, number[]>();
const array = [2, 1];
map.set(1, array.slice()); // use slice here to use the copy
for (const value of array) {
const currentValue = map.get(1);
if (currentValue) {
currentValue.push(array.length + 1);
map.set(1, currentValue);
}
}
slice()
creates a copy of the array. This solves the problem.
Comments