Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript pre-allocated array Uncaught RangeError: Invalid Array Length

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

enter image description here

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}`);

enter image description here

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?

like image 915
Dr. Andrew Burnett-Thompson Avatar asked Dec 02 '21 11:12

Dr. Andrew Burnett-Thompson


People also ask

How do you fix an invalid Array length?

To fix the 'RangeError: invalid array length' when we're developing JavaScript apps, we should make sure the array length value that we call the Array and ArrayBuffer constructors are called with a valid value. Also, we should make sure we set the length property of an array to a non-negative integer.

What is invalid Array length?

The JavaScript exception "Invalid array length" occurs when specifying an array length that is either negative, a floating number or exceeds the maximum supported by the platform (i.e. when creating an Array or ArrayBuffer , or when setting the Array.

How to fix ‘rangeerror invalid array length’?

To fix the ‘RangeError: invalid array length’ when we’re developing JavaScript apps, we should make sure the array length value that we call the Array and ArrayBuffer constructors are called with a valid value. Also, we should make sure we set the length property of an array to a non-negative integer.

What is invalid array length in JavaScript?

The JavaScript exception "Invalid array length" occurs when creating an Array or an ArrayBuffer which has a length which is either negative or larger or equal to 2 32, or when setting the Array.length property to a value which is either negative or larger or equal to 2 32.

What is the cause of arraybuffer length error?

Cause of the error: The length of an Array or an ArrayBuffer can only be represented by an unsigned 32-bit integer, which only stores values ranging from 0 to 2 32 -1. While creating an Array or an ArrayBuffer, if the array length is either negative or greater than or equal to 2 32 then this error occurs.

What is the maximum array length allowed in Java?

The maximum allowed array length depends on the platform, browser and browser version. For Array the maximum length is 2GB-1 (2^32-1). For ArrayBuffer the maximum is 2GB-1 on 32-bit systems (2^32-1).


Video Answer


1 Answers

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.

like image 93
Oleg Imanilov Avatar answered Oct 22 '22 10:10

Oleg Imanilov