Есть ли ограничение на размер строки в JSON с Node.js?

Раздел моего приложения Node.js включает в себя получение строки в качестве ввода от пользователя и сохранение ее в файле JSON. Сам JSON, очевидно, не имеет на это ограничений, но есть ли верхняя граница объема текста, который Node может обрабатывать в JSON?

Обратите внимание, что я не использую MongoDB или любую другую технологию для фактической вставки - это родная строка и сохранение в .json файле с помощью fs.

Ответы

Ответ 1

V8 (на JavaScript построен механизм JavaScript node), пока совсем недавно не было жесткого ограничения на размер кучи около 1,9 ГБ.

Node v0.10 застрял в старой версии V8 (3.14) из-за нарушения изменений API V8 вокруг собственных аддонов. node 0.12 будет обновлен до новейшего V8 (3.26), который сломает многие собственные модули, но откроет дверь для повышения высоты кучи 1.9 ГБ.

Таким образом, единственный процесс node может содержать не более 1,9 ГБ кода JavaScript, объектов, строк и т.д. в сочетании. Это означает, что максимальная длина строки меньше 1,9 ГБ.

Вы можете обойти это, используя Buffer s, которые хранят данные вне кучи V8 (но все еще в вашей куче процесса). 64-битная сборка node может в значительной степени заполнить всю вашу оперативную память, если у вас никогда не будет более 1,9 ГБ данных в переменных JavaScript.


Все, что сказал, вы никогда не должны приближаться к этому пределу. Имея дело с этим большим количеством данных, вы должны иметь дело с ним как с потоком. У вас никогда не должно быть больше нескольких мегабайт (максимум) в памяти за один раз. Хорошей новостью является node, особенно хорошо подходит для работы с потоковыми данными.

Вы должны задать себе несколько вопросов:

  • Какие данные вы фактически получаете от пользователя?
  • Почему вы хотите сохранить его в формате JSON?
  • Разве это действительно хорошая идея наполнить гигабайты в JSON? (Ответ - нет.)
  • Что произойдет с данными позже, после того, как оно будет сохранено? Будет ли ваш код читать? Что-то еще?

Вопрос, который вы опубликовали, на самом деле довольно неопределенна в отношении того, что вы на самом деле пытаетесь выполнить. Для получения более конкретных рекомендаций обновите свой вопрос с дополнительной информацией.

Если вы ожидаете, что данные никогда не будут такими большими, просто введите разумный лимит в 10 МБ или что-то на входе, буферизируйте все это и используйте JSON.stringify.

Если вы планируете обрабатывать данные больше, вам нужно передать поток прямо на диск. Посмотрите трансформировать потоки, если вам нужно обработать/изменить данные перед тем, как перейти на диск. Например, существуют модули, которые работают с потоковым JSON.

Ответ 2

Максимальный размер строки в "vanilla" nodeJS (v0.10.28) находится в шаге 1GB.

Если вы спешите, вы можете проверить максимальный размер поддерживаемой строки с помощью строки с удвоением. В протестированной системе имеется 8 ГБ ОЗУ, в основном неиспользованный.

x = 'x';
while (1){ 
     x = ''+x+x; // string context
     console.log(x.length);
}

2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
16384
32768
65536
131072
262144
524288
1048576
2097152
4194304
8388608
16777216
33554432
67108864
134217728
268435456
536870912
FATAL ERROR: JS Allocation failed - process out of memory
Aborted (core dumped)

В другом тесте я получил до 1 000 000 000 с одним char за цикл.

Теперь критик может сказать: "Подожди, как насчет JSON, вопрос о JSON!" и я бы кричал, что в JAVASCRIPT нет JS-типов JS-типов: Object, Array, String, Number и т.д., а поскольку JSON представляет собой представление String, этот вопрос сводится к тому, что является самой длинной допустимой строкой. Но для двойной проверки добавьте вызов JSON.stringify для адресации преобразования JSON.

код

x = 'x';
while (1){ 
     x = ''+x+x; // string context
     console.log(JSON.stringify({a:x}).length);
}

Ожидания: размер строки JSON будет начинаться больше, чем 2, потому что первый объект будет привязывать к '{ "a": "xx" }' для 10 символов. Он не начнет удваиваться, пока строка x в свойстве a не станет больше. Вероятно, он провалится около 256M, так как он, вероятно, делает вторую копию в строчении. Напомним, стробирование не зависит от исходного объекта.

Результат:

10
12
16
24
40
72
136
264
520
1032
2056
4104
8200
16392
32776
65544
131080
262152
524296
1048584
2097160
4194312
8388616
16777224
33554440
67108872
134217736
268435464

В значительной степени, как ожидалось....

Теперь эти ограничения, вероятно, связаны с кодом C/С++, который реализует JS в проекте nodeJS, который в это время я считаю одним и тем же кодом V8, используемым в браузерах Chrome.

Есть данные из сообщений в блогах людей, которые перекомпилируют nodeJS, чтобы обойти ограничения памяти в более старых версиях. Существует также ряд команд командной строки nodejs. Я не проверял эффект от этого.

Ответ 3

Это хороший вопрос, но я думаю, что верхний предел, о котором вам нужно беспокоиться, не включает в себя максимальный размер строки JSON.

По моему мнению, вам нужно беспокоиться о том, как долго вы хотите заблокировать поток запросов при обработке запроса пользователя.

Любой размер строки более 1 МБ займет у пользователя несколько секунд для загрузки, а 10 мегабайт могут занять несколько минут. После получения запроса сервер займет от нескольких сотен миллисекунд до нескольких секунд, чтобы проанализировать структуру данных, что приводит к очень плохому пользовательскому опыту (Parsing JSON очень дорог)

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