ENOMEM в Node.js, вызванный высоким использованием виртуальной памяти
Я получаю ошибки ENOMEM в моем рабочем приложении Node.js (v12) в течение нескольких месяцев.
Эту проблему было особенно сложно диагностировать, потому что размер моей кучи всегда находится в диапазоне 100 МБ и со временем не увеличивается. Следовательно, утечка памяти узла маловероятна.
Однако иногда использование памяти VIRT (как сообщает top cmd) достигает 15-20 ГБ, и именно тогда узел начинает выдавать некоторые ошибки "spawn: enomem".
Насколько я понимаю, что-то заставляет узел зарезервировать много-много виртуальной памяти, хотя размер кучи стабильно составляет 100 МБ. И я не могу диагностировать, что это такое, поскольку инструменты дебюта узлов позволяют мне только проверять кучу.
Я потратил около 100 часов на эту проблему, поэтому я буду благодарен за любую информацию / помощь!
Я попытался:
- Ручная установка --max-old-space-size
- Увеличение оперативной памяти на сервере
- Добавление SWAP на мой сервер и разрешение докеру использовать этот SWAP
- Проверка кучи узлов с помощью инструментов chrome dev
- Установка лимита памяти для моих контейнеров докеров
- Переход к другому менеджеру процессов (pm2 вместо supervisord)
- обновление всех моих пакетов и использование последней LTS-версии узла
- Чтение и понимание всех результатов Google для узла ENOMEM
- Понимание того, как Node управляет своим пулом памяти, особенно в отношении кучи и GC.
- Погружение в концепции ядра Linux о виртуальной, зарезервированной, подкачиваемой и общей памяти.
Спасибо за вашу помощь!
1 ответ
Нам удалось решить проблему. Имейте в виду, что решение может быть специфическим для нашего собственного проекта.
Нам удается последовательно воспроизвести ошибку при использовании пакета "imagemin" с "imagemin-jpegtran" и "imagemin-pngquant" на большом массиве (20 КБ +) файлов и ожидании завершения всех обещаний с помощью prom.all (). Использование памяти VIRT увеличилось до 20 ГБ + и никогда не освобождалось после выполнения.
Решением для нас было использование plimit, чтобы ограничить количество одновременных обещаний до 5 или 10. На том же количестве изображений (20k+) использование памяти VIRT никогда не увеличивалось, равно как и RES, и мы перестали получать ошибки ENOMEM.
Надеюсь, это поможет кому-то там