Проблемы с памятью NodeJS v14: Резидентный набор сильно растет

После того, как я обновил серверное приложение NodeJS с версии 6 до версии 14, я столкнулся со странным поведением памяти.

Я заметил эту проблему (если она есть), когда анализировал использование памяти с помощью Dynatrace:

  1. процесс не дает никаких проблем, ни перезапусков, ни сбоев не было: все работает нормально

  2. общее использование памяти постоянно увеличивается, пока не достигнет примерно 5 ГБ (мы использовали опцию --max-memory-restart 5G при запуске приложения — кто знает, имеет ли это какое-то отношение к этому ...)

  3. Размер кучи имеет обычное значение и остается стабильным в районе 100~150 МБ.

  4. Резидентный набор постоянно растет, пока не достигнет 5 ГБ, и никогда не нарушал этот лимит (более того: функции безопасности перезапуска никогда не срабатывали)

  5. Я сталкиваюсь с этой проблемой только в NodeJS v14, а не в NodeJS v6, базовый код приложения тот же

Некоторые подробности об использовании памяти здесь:

введите здесь описание изображения

введите здесь описание изображения

У меня нет больших знаний о структуре и использовании памяти JS Engine V8, но я прочитал следующие лекции:

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


person shogitai    schedule 11.12.2020    source источник
comment
Если размер кучи остается стабильным, то я бы не стал беспокоиться о резидентном наборе, если он не вызывает у вас проблем. Это просто вопрос о том, когда и действительно ли nodejs возвращает память ОС. Пока он не растет постоянно, у вас стабильная ситуация без каких-либо долгосрочных утечек.   -  person jfriend00    schedule 11.12.2020
comment
Когда вы упоминаете V4 и V8, о какой версии вы говорите? Версия nodejs (которая сейчас на v14/v15)? Или внутреннюю версию интерпретатора Javascript? V8 в вашем A Tour of V8: Garbage Collection — это название интерпретатора JS, который создает Google, а не номер версии.   -  person jfriend00    schedule 11.12.2020
comment
После лекций я мог перепутать версии движков JS и версии NodeJS: на самом деле я имел в виду переход с NodeJS v6 на NodeJS v14. Я обновил ответ, извините и спасибо за разъяснения.   -  person shogitai    schedule 13.12.2020


Ответы (2)


На диаграмме памяти v8 Dynatrace не только показывает память кучи, но и сравнивает ее с размером резидентного множества всего процесса. Некоторых это может сбить с толку, но это очень помогает отделить утечки памяти JS от утечек собственной памяти. В вашем случае, похоже, существует потенциальная утечка собственной памяти, вызванная собственными модулями.

Вы упомянули параметр --max-memory-restart, поэтому я предполагаю, что вы используете PM2. В официальной документации неясно, отслеживает ли инструмент только память, используемую в куче, или общее использование памяти. Согласно этой статье, кажется, что PM2 не умеет покрывать и родную память. Еще более интересен этот отчет об ошибке (закрыт, но согласно последним комментариям еще не исправлен) и принятый ответ на это вопрос о переполнении стека. Кажется, что даже ваша версия PM2 может содержать собственные утечки памяти.

Здесь вы можете найти дополнительную информацию о том, как анализировать утечку собственной памяти в NodeJS. Принятый ответ в упомянутом выше вопросе также перечислены некоторые ссылки на альтернативы для PM2.

Кстати, Dynatrace сообщит вам, должно ли увеличение использования памяти иметь какое-либо измеримое негативное влияние на ваши службы/приложения или на работу конечного пользователя.

person rmunge    schedule 13.12.2020

Я обновил серверное приложение NodeJS с версии 4 до версии 8. [...] Я сталкиваюсь с этой проблемой только в V8, а не в V4

Уточнение терминов: каждая версия Node построена на основе движка JavaScript V8 (у которого есть версии, которые в настоящее время быть 8.x, но это отличается от его названия: раньше у нас была V8 v7.x, а скоро у нас будет V8 v9.x).

Если вы действительно имеете в виду, что вы только что обновились с Node версии 4.x до Node версии 8.x, то, пожалуйста, просто обновитесь дальше: по крайней мере, до Node версии 12.x, еще лучше 14.x.

Я не знаком с Dynatrace, но эти графики немного сбивают с толку. Не существует такой вещи, как размер резидентного набора памяти кучи V8: весь процесс имеет размер резидентного набора, и часть того, что там находится, является памятью кучи V8. Но поскольку последний, по-видимому, остается на уровне ~ 150 МБ, это не дает нам никакого представления о росте первого. Сборка мусора V8 влияет на его кучу, а не на RSS. Трудно предположить, что там происходит, но...

Поскольку это не вызывает у меня никаких реальных проблем, могу ли я приукрашивать?

...Конечно. Давайте использовать наше коллективное время для решения важных проблем.

person jmrk    schedule 12.12.2020
comment
Извините, я перепутал версии движка JS с версиями NodeJS: я обновил ответ. - person shogitai; 13.12.2020