I have a small loop of code which is throwing Uncaught RangeError: Invalid Array Length
I was able to reproduce it with just this in the Google Chrome console
const COUNT = 100_000_000;
const xValues = new Array(COUNT);
const yValues = new Array(COUNT);
for (let i = 0; i < COUNT; i ) {
xValues[i] = i;
yValues[i] = Math.sin(i * 0.000001);
}
console.log(`count: ${yValues.length}`);
Here's the output in developer console
As far as I know the maximum array size in Javascript is 2^32-1? There should be enough memory to allocate here and the index i is never negative or outside the bounds of the array as far as I can see.
Curiously enough, if I use this code, there is no crash
const COUNT = 100_000_000;
const xValues = new Array(COUNT);
const yValues = new Array(COUNT);
for (let i = 0; i < COUNT; i ) {
xValues[i] = i;
yValues[i] = i;
}
console.log(`count: ${yValues.length}`);
The value assigned to yValues[i] never goes outiside of the range -1, 1 so I can't see this as a number out of range problem either.
Anyone shed any light on this?
EDIT: Update
Another scenario that doesn't work. Computing a random walk.
const count = 100_000_000;
const xValues = new Array(COUNT);
const yValues = new Array(COUNT);
let prevYValue = 0;
for (let i = 0; i < COUNT; i ) {
const curYValue = Math.random() - .5;
xValues[i] = i;
yValues[i] = prevYValue curYValue;
prevYValue = curYValue;
}
This one throws as well! But
yValues[i] = i
is fine ¯\_(ツ)_/¯
EDIT: Update 2
Can now confirm this is browser specific, if you run the same test in firefox it works, but the browser asks you to wait.
Suspect the exception Uncaught RangeError
is a badly reported timeout?
CodePudding user response:
The real reason is in V8 memory optimization. When you store integers - it stores the 32 bit number in place, But when you store double-number - it is stored differently (as an object) - so yValues
array contains the reference but the actual value stored in heap. So in your example you just used all heap memory. To see the limit, use: console.memory
and you'll see something like this:
MemoryInfo {
totalJSHeapSize: 10000000,
usedJSHeapSize: 10000000,
jsHeapSizeLimit: 3760000000}
In my browser it is 3_760_000_000
The object on heap takes 50 bytes, so my limit somewhere around 69_000_000 floating point numbers.