JavaScript pre-allocated array Uncaught RangeError: Invalid Array Length - Stack Overflow

I have a small loop of code which is throwing Uncaught RangeError: Invalid Array LengthI was able to r

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?

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?

Share Improve this question edited Dec 2, 2021 at 14:07 Dr. Andrew Burnett-Thompson asked Dec 2, 2021 at 11:55 Dr. Andrew Burnett-ThompsonDr. Andrew Burnett-Thompson 21.6k8 gold badges91 silver badges186 bronze badges 14
  • 1 Interesting! It fails when i reaches 5,592,406 FYI (on my machine at least). – sp00m Commented Dec 2, 2021 at 12:07
  • 1 Chrome and Edge break both on the Math.sin() row when i === 5592406. If you start at 5592406 it breaks on 11184812 or (5592406 * 2), and the same for (5592406 * 3) ... – Andreas Commented Dec 2, 2021 at 12:09
  • 3 yValues[5592406] = Math.sin(5592406 * 0.000001) alone passes, so the RangeError does not seem to relate only to the number of indexes, but also somehow to the content being stored in the array? MDN doesn't make this behaviour explicit IMHO. – sp00m Commented Dec 2, 2021 at 12:13
  • 2 It is not related to putation. You get the same with just one array, and assigning a float to it, like 0.5. The difference in behaviour is clearly linked to the internal data type that is used for the array elements: either 32-bit integers or floats. See the difference in assigning 1e9 (is a 32-bit integer) or 1e10 (not a 32-bit integer). It is not related to calling Math.random or Math.sin. – trincot Commented Dec 2, 2021 at 14:17
  • 2 Done, reported as a possible Chromium bug bugs.chromium/p/chromium/issues/detail?id=1275993 – Dr. Andrew Burnett-Thompson Commented Dec 2, 2021 at 15:33
 |  Show 9 more ments

1 Answer 1

Reset to default 8

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.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742361906a4429555.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信