如果内存足够,为什么不能 v8/nodejs 分配最大大小的数组?
Why cannot v8/nodejs allocate a max-size array if sufficient memory?
我知道 JavaScript 数组的最大长度是 2^32-1,但无论我允许多少内存,它仍然无法分配。这是怎么回事?一线复现:
node --max-old-space-size=100000 -e "console.log(v8.getHeapStatistics().total_available_size);Array.from({ length: Math.pow(2, 32)-1 })"
为清楚起见,上面的示例向 v8 公开了 100GB,这已通过 total_available_size
确认。 8GB 可能足以测试此操作,因为大多数人不会有 100GB,但无论如何它都会失败。这是 V8 中的错误吗?
(此处为 V8 开发人员。)
不,这不是错误,只是实现定义的限制。 V8 对任何单个堆对象都有 ~1GB 的内部限制。每个元素 4 个字节(使用指针压缩),这意味着每个数组最多 ~256M 个元素。
还有很多其他实现定义的限制,例如对于 TypedArray 长度、字符串长度、BigInt 大小、递归深度、每个函数的参数数量、Map 中的条目数量等。几乎所有东西都有限制,即使 JavaScript 规范没有明确提及,或提到与实现限制不同的理论限制(隐式假定存在)。
我知道 JavaScript 数组的最大长度是 2^32-1,但无论我允许多少内存,它仍然无法分配。这是怎么回事?一线复现:
node --max-old-space-size=100000 -e "console.log(v8.getHeapStatistics().total_available_size);Array.from({ length: Math.pow(2, 32)-1 })"
为清楚起见,上面的示例向 v8 公开了 100GB,这已通过 total_available_size
确认。 8GB 可能足以测试此操作,因为大多数人不会有 100GB,但无论如何它都会失败。这是 V8 中的错误吗?
(此处为 V8 开发人员。)
不,这不是错误,只是实现定义的限制。 V8 对任何单个堆对象都有 ~1GB 的内部限制。每个元素 4 个字节(使用指针压缩),这意味着每个数组最多 ~256M 个元素。
还有很多其他实现定义的限制,例如对于 TypedArray 长度、字符串长度、BigInt 大小、递归深度、每个函数的参数数量、Map 中的条目数量等。几乎所有东西都有限制,即使 JavaScript 规范没有明确提及,或提到与实现限制不同的理论限制(隐式假定存在)。