Резюме
Загрузка изображения из серверной части Nodejs в AWS S3 через JIMP заполняет кучу памяти.
Workflow
- Frontend (реагирует) отправляет изображение через форму отправки в API
- Сервер анализирует данные формы
- JIMP поворачивает изображение
- JIMP изменяет размер изображения, если ширина> 1980px
- JIMP создает буфер
- Буфер загружается на S3
- Обещание разрешено -> Метаданные изображения (URL, имя корзины, индекс и т. Д.), Сохраненные в базе данных (MongoDB)
Фон
Сервер размещен на Heroku с оперативной памятью всего 512 МБ. Загрузка небольших изображений и все другие запросы работают нормально. Тем не менее, приложение вылетает при загрузке одного изображения размером более ~ 8 МБ, когда в сети только один пользователь.
Расследование до настоящего времени
Я пытался повторить это в моей локальной среде. Поскольку у меня нет ограничения памяти, приложение не будет аварийно завершать работу, но при загрузке изображения размером 10 МБ используется около 870 МБ. Образ 6 МБ остается около 60 МБ оперативной памяти. Я обновил все пакеты npm и попытался отключить любую обработку изображения.
Я пытался искать утечки памяти, как показано на следующих снимках экрана, однако, следуя тому же рабочему процессу, что и выше, для того же изображения (6 МБ) и делая 3 снимка кучи, мы получаем около 60 МБ памяти.
Во-первых, я подумал, что проблема в том, что обработка изображения (изменение размера) занимает слишком много памяти, но это не объясняет большой разрыв между 60 МБ (для изображения 6 МБ) и около 800 МБ для изображения 10 МБ.
Тогда я подумал, что это связано с элементом "system / JSArrayBufferData" (см. Ссылку 2), который занимает около 30% памяти. Тем не менее, этот пункт всегда есть, даже я не загружаю изображение. Он появляется только перед тем, как я остановлю снимок записи на вкладке «Память» в разделе «Инструменты разработчика Chrome». Тем не менее, я все еще не уверен на 100%, что именно.
Теперь я считаю, что это связано с «TimeList» (видно в ref3). Я думаю, что это связано с тайм-аутами в ожидании загрузки файла на S3. Однако и здесь я абсолютно не уверен, почему это происходит.
Ниже приведены снимки экрана, на мой взгляд, важных частей снимков Chrome Inspector, работающих на сервере на nodejs с флагом --inspect.
Ref1: Показывает полные элементы 3-го снимка - все 3 снимка загрузили одно и то же изображение размером 6 МБ. Мусор кажется правильно собранным, так как объем памяти не увеличился
Ref2: Показывает окончание третьего снимка, непосредственно перед тем, как я остановил запись. Не уверены, что такое «system / JSArrayBufferData».
Ref3: Показывает конец 5-го снимка, это изображение с размером 10 МБ. Эти маленькие непрерывные всплески - это элементы «TimeList», которые, похоже, связаны с тайм-аутом. Кажется, они появляются, когда сервер ожидает ответа от AWS. Также кажется, что это то, что заполняет память, так как этот элемент отсутствует при загрузке чего-то менее 10 МБ.
Ref4: Показывает немедленное завершение 5-го снимка непосредственно перед остановкой записи. «system / JSArrayBufferData» появляется снова, но только в конце.
![](https://i.stack.imgur.com/QS2No.png)
Вопрос
К сожалению, я не уверен, как сформулировать свой вопрос, поскольку я не знаю, в чем проблема или на что мне действительно нужно обратить внимание. Буду очень признателен за любые советы или опыт.