Получить доступ

Java-приложение запускают в контейнере с лимитом памяти. Как правильно задать размер кучи?

MiddleJVM и сборка мусора
Коротко

Задавать кучу долей от лимита: -XX:MaxRAMPercentage=70–75, оставляя запас на память вне кучи (Metaspace, стеки, кодовый кэш, direct-буферы, GC). -Xmx, равный лимиту, приводит к OOMKilled без OutOfMemoryError в логах.

  • Современные JVM (10+, 8u191+) видят лимиты cgroup
  • По умолчанию куча — всего 25% от лимита
  • Число CPU в контейнере влияет на выбор GC и размеры пулов

А ещё Native Memory Tracking (-XX:NativeMemoryTracking) — что съело память вне кучи

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Ключевая ошибка — приравнять -Xmx к лимиту: помимо кучи процесс расходует Metaspace, стеки потоков, кодовый кэш, direct-буферы и накладные расходы сборщика, поэтому суммарное потребление превысит лимит и контейнер будет убит по нехватке памяти, причём без всякого OutOfMemoryError в логах приложения — что сильно затрудняет диагностику. Задание доли процентом удобнее ещё и потому, что переживает изменение лимита без правки команды запуска. Отдельно стоит помнить историю вопроса: старые версии JVM не видели лимитов cgroups и определяли память по хосту, из-за чего в контейнерах регулярно случались внезапные завершения; в современных версиях учёт контейнера включён по умолчанию.

Что хотят услышать

  • Почему -Xmx = лимит опасен.
  • MaxRAMPercentage.
  • Из чего состоит память вне кучи.

Частые ошибки

  • Ставить -Xmx равным лимиту контейнера.
  • Искать причину падения в логах приложения, когда процесс убит извне.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Задать долю от лимита через MaxRAMPercentage — современные JVM учитывают ограничения cgroups и вычисляют кучу от лимита контейнера
  • ✗Не задавать ничего: JVM всегда определяет доступную память по лимиту контейнера идеально
  • ✗Выставить -Xmx равным лимиту контейнера
  • ✗Отключить учёт контейнера, чтобы JVM видела всю память хоста

Что спросят дальше

  • Какие области памяти расходуются вне кучи?
  • Как понять, что контейнер был убит по лимиту памяти, а не упал сам?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем