ENOMEM в Node.js вызвано высоким использованием виртуальной памяти - PullRequest
3 голосов
/ 25 мая 2020

Я получаю ошибки ENOMEM в моем рабочем приложении Node.js (v12) в течение нескольких месяцев.

Эту проблему было особенно сложно диагностировать, потому что моя куча всегда находится в диапазоне 100 МБ и не увеличивается со временем. Следовательно, утечка памяти узла маловероятна.

Однако иногда использование памяти VIRT (как сообщает top cmd) достигает 15-20 ГБ, и именно тогда узел начинает выдавать некоторые ошибки "spawn: enomem" .

Насколько я понимаю, что-то заставляет узел зарезервировать много-много виртуальной памяти, хотя размер кучи стабильно составляет 100 МБ. И я не могу диагностировать, что это такое, поскольку инструменты дебюта узла позволяют мне только осматривать кучу.

Я потратил около 100 часов на эту проблему, так что любое понимание / помощь будет действительно признательно!

Я пробовал:

  • Ручная установка --max-old-space-size
  • Увеличение ОЗУ на сервере
  • Добавление SWAP на мой сервер и разрешение docker использовать этот SWAP
  • Проверка кучи узлов с помощью chrome инструментов разработчика
  • Установка ограничения памяти для моих docker контейнеров
  • Переход к другому диспетчер процессов (pm2 вместо supervisord)
  • обновление всех моих пакетов и использование последней версии LTS узла
  • Чтение и понимание всех результатов Google для узла ENOMEM
  • Понимание того, как Узел управляет своим пулом памяти, особенно в отношении кучи и G C.
  • Углубляясь в концепции linux ядра виртуальной, зарезервированной, подкачки и разделяемой памяти.

Спасибо за ваше помогите!

1 Ответ

1 голос
/ 25 августа 2020

Нам удалось решить проблему. Имейте в виду, что решение может быть указано c для нашего собственного проекта.

Нам удается последовательно воспроизводить ошибку при использовании пакета «imagemin» с «imagemin-jpegtran» и «imagemin-pngquant» на большой массив (20k +) файлов и ожидание завершения всех обещаний sh с помощью обещания.all (). Использование памяти VIRT увеличилось до 20 ГБ + и не было освобождено после выполнения.

Решение для нас заключалось в использовании plimit , чтобы ограничить количество одновременных обещаний до 5 или 10. То же самое. количество изображений (20k +) использование памяти VIRT никогда не увеличивалось, как и RES, и мы перестали получать ошибки ENOMEM.

Надеюсь, это поможет кому-то ?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...