Пределы искусственной производительности в V8/nodejs

V8 способен переборщить много памяти с помощью --max-old-space-size. Я регулярно использую node для задач, требующих 10 ГБ +, это здорово - память дешевая и намного быстрее, чем чтение/запись с/на диск.

Однако, когда я сталкиваюсь с трудностями, я пытаюсь создать очень большие индивидуальные массивы/карты/объекты. Я получаю сообщения об ошибках:

FATAL ERROR: invalid table size Allocation failed - JavaScript heap out of memory

И это:

RangeError: Invalid array length

В обоих случаях это не то, что мой компьютер не может справиться с этим, или что у меня закончилась память - это потому, что в V8 скрываются некоторые коварные искусственные ограничения.

Чтобы получить ошибку диапазона, бросьте это в своем терминале: node -e "new Array(5*1000*1000*1000)"

И для получения недопустимой ошибки размера таблицы: node -e "(new Array(200*1000*1000)).fill(1)"

Эти искусственные пределы хорошо известны (1, 2) и, по-видимому, из-за какого-то старого кода сборщика мусора, который команда V8 боится трогать, знает, что потребуется много работы для исправления (см. chromium отчет об ошибках).


Вопрос:

Кому хорошо известны дорожные карты V8 и nodejs: будут ли эти ограничения когда-либо отменены? Как долго мы можем ждать, примерно?

Обратите внимание, что я понимаю шаблоны для более низкого использования памяти, такие как потоковая передача, и я знаю, что nodejs и V8 не были созданы для "больших данных" - этот вопрос касается не того, как оптимизировать использование памяти и т.п. Просто интересуйтесь дорожными картами V8 и nodejs с точки зрения этих искусственных ограничений.

Ответ 1

Разработчик V8 здесь. Короче говоря, это не по дорожной карте, извините.

Мы знаем, что ограничение размера массивов и строк неудобно. Тем не менее, повышение существующих лимитов будет большим количеством усилий. Мы хотели бы сделать это в какой-то момент, но сейчас у него нет приоритета. (Это в значительной степени то, что суммируется ошибка, о которой вы говорили, - мы не так боимся, это просто нетривиально, потому что это не просто "коварный искусственный лимит", и у нас нет времени для он дал другие приоритеты.)

Это не просто вопрос об усилиях, есть и технические соображения. Поддержка произвольных длин, хотя это возможно, сделает некоторые операции более медленными. Мы признаем, что некоторые примеры использования действительно выиграют от этой повышенной гибкости, но другие варианты использования выигрывают от скорости, которая достигается благодаря более простой и быстрой базовой реализации. Поиск правильного баланса не является очевидным. Кроме того, нам по-прежнему приходится поддерживать 32-разрядные платформы, где размер указателя ставит довольно низкие пределы, например. размеры объектов, и мы как можно больше хотим иметь одинаковое поведение, независимо от того, какое оборудование или ОС. Эта часть точки наличия виртуальной машины JavaScript в первую очередь...

Говоря о JavaScript: спецификация ECMAScript определяет, что new Array(n) выбрасывает RangeError всякий раз, когда n != ToUint32(n). 5*1000*1000*1000 не является uint32. Так что этот конкретный случай на самом деле требует поведения; если V8 должен был поддерживать такие массивы, это нарушало бы спецификацию.