«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Оптимизация настройки кучи Java для AWS ECS

Оптимизация настройки кучи Java для AWS ECS

Опубликовано 6 ноября 2024 г.
Просматривать:643

Optimizing Java Heap Setting for AWS ECS

Мы запускаем несколько сервисов Java (Corretto JDK21) на AWS Elastic Container Service (ECS) Fargate. У каждого сервиса есть свой контейнер, и мы хотим использовать все возможные ресурсы, которые платим за каждый процесс. Но эти шаги можно применить к EC2 и другим облакам.

Сервисы выполняют пакетные задания, и задержка не важна, мы используем Parallel GC (-XX: UseParallelGC). Возможно, G1 и с нашими задачами справился бы лучше, но это тема для отдельного исследования и поста.
Чтобы использовать всю доступную память, мы устанавливаем MaxHeapSize немного меньшим, чем размер памяти контейнера. Но через некоторое время мы заметили две проблемы: иногда наши контейнеры закрывались, потому что они использовали слишком много памяти, а иногда мы получали исключения OutOfMemoryError. Чтобы исправить первое, мы увеличили разрыв между размером памяти контейнера и MaxHeapSize, а для второго увеличили память контейнеров в качестве быстрого решения и начали просматривать дампы кучи.

Дампы кучи показали интересные детали, фактический размер кучи был меньше, чем MaxHeapSize, а куча молодого поколения была крошечной по сравнению с кучой старого поколения.

Поиск в Интернете не помог найти хорошее руководство о том, как настроить параметры JVM для нашего случая, я нашел только некоторые общие сведения о кучах и описаниях параметров. Я решил написать этот пост, чтобы описать шаги, которые я сделал.

Первыми шагами были:

  • распечатать информацию о параметрах и значениях по умолчанию: (-XX: PrintFlagsFinal),
  • установите для InitialHeapSize то же значение, что и для MaxHeapSize (-XX:InitialRAMPercentage=100, или просто установите для -XX:InitialHeapSize то же значение, что и для MaxHeapSize). В любом случае мы платим за всю память контейнера, так почему бы не выделить ее с самого начала?
  • регистрировать сборщик мусора и информацию о куче (-Xlog:gc*).

Соотношение по умолчанию для молодых:старых поколений составляет 1:2, и только часть молодого поколения одновременно используется для выполнения GC. И после запуска JVM как и положено распределила всю память, но через некоторое время начала уменьшать размер кучи Young Generation почти до нескольких мегабайт. Итак, через некоторое время мы использовали всего ⅔ доступной памяти.
Покопавшись, я нашел параметр для отключения Adaptive Policy (-XX:-UseAdaptiveSizePolicy) и это помогло, куча перестала уменьшаться, а интервалы между сборками мусора увеличились на порядок, а то и больше. Время, затрачиваемое сборщиком мусора, тоже выросло, но не так сильно.

Следующим шагом было найти оптимальный разрыв между размером памяти контейнера. По умолчанию, даже если InitialRAMPercentage=100, JDK просто выделяет память и не использует ее, поэтому она не отображается. Linux позволяет ему выделять больше виртуальной памяти, чем имеется физической памяти. И контейнер выходит из строя позже, когда память фактически отображается (JDK записывает в нее). -XX: AlwaysPreTouch меняет это поведение. К сожалению, часть памяти по-прежнему не отображается, но завершение OOM происходит намного быстрее. После нескольких попыток я закончил следующей формулой «Размер памяти контейнера» — 1024 МБ для контейнеров с 8 ГБ памяти и более. Например, для размера памяти контейнера 8192 мы используем -XX:MaxHeapSize=7168m.

Для дальнейшей оптимизации мы думаем об изменении -XX:NewRatio, чтобы уменьшить размер Young Generation и сократить время сборки мусора. Но это зависит от времени жизни объекта в приложении.
Как я уже упоминал ранее, я не нашел хорошего руководства с подробным объяснением параметров (лучшее, что я нашел, это vm-options-explorer) и этапов настройки. Будет здорово, если вы поделитесь своими знаниями и результатами.

Заявление о выпуске Эта статья воспроизведена по адресу: https://dev.to/mikhail-m1/optimizing-java-heap-setting-for-aws-ecs-5df6?1. Если есть какие-либо нарушения, свяжитесь с [email protected], чтобы удалить это
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3