Проблемы с памятью при переходе на JDK 17

Команда Spring АйО провела анализ проблем с памятью, возникших после перехода с JDK 8 на JDK 17. Обновление прошло успешно на этапе разработки и QA, однако в продакшене система начала давать сбои через несколько часов после развертывания.

  • Увеличение потребления памяти в 4 раза
  • Контейнеры начали перезапускаться из-за OOMKill
  • Рост количества потоков до 1600+
  • Проблемы с нативной памятью, увеличившейся с 800 MB до 3.6 GB

Анализ причин возникновения проблем

При миграции на JDK 17 возникли три ключевые проблемы, усугубленные контейнеризацией:

  1. Неверное определение CPU: JVM неправильно определила количество доступных процессоров, что привело к увеличению числа потоков.
  2. Фрагментация malloc-арен: Из-за увеличения числа потоков glibc создала слишком много арен памяти.
  3. Накладные расходы G1GC: Переход на новый сборщик мусора увеличил потребление нативной памяти.

Решения и рекомендации

Для устранения проблем были предложены следующие меры:

Решение Описание
-XX:ActiveProcessorCount=2 Явно задать количество процессоров для JVM.
export MALLOC_ARENA_MAX=2 Ограничить количество malloc-арен glibc.
Настройка G1GC или переход на ParallelGC Оптимизация сборки мусора для снижения накладных расходов.

После внедрения этих решений, использование памяти стабилизировалось на уровне 65-70%. Команда также внедрила Native Memory Tracking (NMT) для более детального мониторинга нативной памяти и установила алерты для отслеживания роста числа потоков.

Опыт перехода на JDK 17 стал важным уроком, подчеркнув необходимость внимательного подхода к обновлениям JVM и мониторингу потребления памяти в контейнеризованных средах.

Понравилась статья? Поделиться с друзьями: