нужен способ обойти ошибку "узел исчерпал память" - PullRequest
0 голосов
/ 18 февраля 2019

Я анализирую ~ 250K XML и загружаю данные в базу данных SQLite.Я использую версию узла 10.15.1 с cheerio и better-sqlite3 на ноутбуке Mac OS X с 8 ГБ памяти.Я readdirSync - работаю со всей папкой ~ 250K файлов, анализирую XML-файлы и загружаю извлеченные данные, используя транзакции в пакетах по 10K.Я использую --max_old_space_size=4096, но все еще получаю ФАТАЛЬНАЯ ОШИБКА: неэффективные отметки-компакты близки к пределу кучи. Выделение не удалось - куче JavaScript не хватает памяти .

Теперь, если я обрабатываю файлы размером 100 КБ,выйдите из узла, затем запустите снова и обработайте оставшиеся ~ 150K файлов, после чего все заработает.Но я бы предпочел сделать все это за один раз, поскольку это то, что нужно делать без присмотра.Могу ли я сделать что-нибудь еще, учитывая мои ограничения?Я не могу использовать машину с большим объемом памяти, потому что у меня нет доступа к ней.Я мог бы попытаться увеличить --max_old_space_size немного больше, или я мог бы попытаться сделать меньшие пакеты транзакций, но я не уверен, поможет ли это (я пробовал с 8000 файлов на транзакцию вместо 10 КБ, но это слишком исчерпало память).Единственное, что сейчас помогает, это выход из узла между ними.Могу ли я имитировать это?То есть сказать узлу освободить всю память и сделать вид, что она была перезапущена?Есть еще мысли?

1 Ответ

0 голосов
/ 19 февраля 2019

Итак, я наконец-то наткнулся на решение своей проблемы (я использую «спотыкаться», потому что я не уверен, что это определенно правильная стратегия, но она работает для меня).

Я обнаружил, что на самом делеувеличение значения --max_old_space_size мне не очень помогло.В любом случае, как я уже упоминал выше, мой MacBook имеет только 8 ГБ, поэтому у меня все равно низкий лимит.Наоборот, что помогло, так это просто уменьшить размер моей партии.Таким образом, вместо обработки 10K XML, хранения их данных в памяти, а затем вставки их в транзакцию в SQLite, я обрабатывал 1K XML за раз.Конечно, для обработки ~ 250К файлов мне пришлось иметь дело с 250 циклами вместо 25 циклов, но это не слишком увеличивало мое время.Я обнаружил, что время обработки довольно линейное, около 5K мс на 1K файлов (или 50K мс на 10K файлов).SQLite работает довольно быстро, независимо от того, добавляю я 1K или 10K INSERT в транзакцию, но это мой процесс парсера XML, который начинает работать при работе с очень большими объемами данных.На самом деле, это может также не быть проблемой с cheerio (что, я считаю, очень хорошо).Это может быть мой стиль кодирования, который может быть значительно улучшен.

В любом случае, обработка транзакций 1K с --max_old_space_size=2048 сделала свою работу для меня.Использование памяти узлом (как показано в Activity Monitor было довольно стабильным, и весь дамп файлов 250 КБ был проанализирован и загружен в БД примерно за 42 минуты. Я могу с этим смириться.

...