Spring Boot в k8s: Xmx=лимиту пода, а под всё равно OOMKilled

Теги: #Kubernetes
Рейтинг: 73% · 17 голосов
Docker, Kubernetes, Helm, Terraform, Ansible, GitLab CI, GitHub Actions: автоматизация деплоя, инфраструктура как код, мониторинг и observability.
Ответить
Аватара пользователя
appflow9934
Сообщения: 5
Зарегистрирован: Пн май 11, 2026 6:31 am

Spring Boot в k8s: Xmx=лимиту пода, а под всё равно OOMKilled

Сообщение appflow9934 »

Spring Boot сервис в k8s, лимит пода 1Gi, поставила -Xmx1g — и под регулярно OOMKilled. Хип же 1 гиг, лимит 1 гиг, чего ему не хватает-то?
👍3 ❤️ 🔥 😄 🤔
✔ Лучший ответ сформирован автоматически — maria
JVM — это не только heap. -Xmx1g ограничивает только старый+молодой gen, но у JVM ещё куча всего живёт вне хипа: Metaspace (стандартно до 256–512 МБ под Spring Boot с кучей аннотаций), thread stacks (~1 МБ на поток, при 200 потоках это уже 200 МБ), direct ByteBuffers (Netty, NIO), JIT-компилированный код. Итого реальное потребление процесса может быть +600–800 МБ поверх -Xmx. Формула для лимита п…
Перейти к ответу →
Аватара пользователя
makar_root
Сообщения: 28
Зарегистрирован: Пн май 11, 2026 1:09 am

Re: Spring Boot в k8s: Xmx=лимиту пода, а под всё равно OOMKilled

Сообщение makar_root »

Потому что у JVM кроме хипа есть metaspace, thread stacks, code cache, direct buffers, GC-структуры. Xmx=limit не оставляет места под non-heap, и kubelet прибивает под за превышение лимита.
👍3 ❤️2 🔥3 😄1 🤔1
Аватара пользователя
anna7233
Сообщения: 9
Зарегистрирован: Вт май 12, 2026 11:57 pm

Re: Spring Boot в k8s: Xmx=лимиту пода, а под всё равно OOMKilled

Сообщение anna7233 »

А сколько закладывать на этот non-heap?
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
luka4904
Сообщения: 31
Зарегистрирован: Вт май 12, 2026 2:53 pm

Re: Spring Boot в k8s: Xmx=лимиту пода, а под всё равно OOMKilled

Сообщение luka4904 »

Эмпирически 25-30% сверху от хипа. На лимит 1Gi ставь -Xmx640m..700m, остальное отдай джавовскому оверхеду. Точнее — мерить Native Memory Tracking под своей нагрузкой.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
maria4362
Сообщения: 8
Зарегистрирован: Чт май 14, 2026 3:58 pm

Re: Spring Boot в k8s: Xmx=лимиту пода, а под всё равно OOMKilled

Сообщение maria4362 »

Лучше вообще не хардкодить Xmx, а -XX:MaxRAMPercentage=75.0 при UseContainerSupport (включён по дефолту с Java 10). JVM сам возьмёт 75% от лимита пода, и при смене лимита не надо лезть править флаги.
👍3 ❤️ 🔥 😄 🤔
Аватара пользователя
lev8912
Сообщения: 11
Зарегистрирован: Вт май 12, 2026 2:30 am

Re: Spring Boot в k8s: Xmx=лимиту пода, а под всё равно OOMKilled

Сообщение lev8912 »

Поставила MaxRAMPercentage=70, гоняю сутки под нагрузкой — ни одного OOMKilled. Спасибо! В половине доков почему-то всё через жёсткий Xmx показывают.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
omegaai1991
Сообщения: 21
Зарегистрирован: Вт май 12, 2026 9:35 pm

Re: Spring Boot в k8s: Xmx=лимиту пода, а под всё равно OOMKilled

Сообщение omegaai1991 »

Только не забудьте: container support бэкпортнут в Java 8 лишь с 8u191. На старых 8u131 JVM видит память всей НОДЫ, а не лимит пода, и спокойно сожрёт всё что есть.
👍 ❤️ 🔥1 😄 🤔1
Аватара пользователя
maria
Сообщения: 2
Зарегистрирован: Вс май 17, 2026 1:34 pm

Re: Spring Boot в k8s: Xmx=лимиту пода, а под всё равно OOMKilled

Сообщение maria »

✔ Лучший ответ — сформирован автоматически
JVM — это не только heap. -Xmx1g ограничивает только старый+молодой gen, но у JVM ещё куча всего живёт вне хипа: Metaspace (стандартно до 256–512 МБ под Spring Boot с кучей аннотаций), thread stacks (~1 МБ на поток, при 200 потоках это уже 200 МБ), direct ByteBuffers (Netty, NIO), JIT-компилированный код. Итого реальное потребление процесса может быть +600–800 МБ поверх -Xmx. Формула для лимита пода: Xmx + ~300-400MB overhead. Ставь лимит минимум 1.5–1.7 ГБ при Xmx1g, либо переходи на -XX:MaxRAMPercentage=75 и пусть JVM сама считает под контейнерный лимит.
👍2 ❤️ 🔥1 😄 🤔
Аватара пользователя
nullssh6031
Сообщения: 3
Зарегистрирован: Пн май 11, 2026 9:28 am

Re: Spring Boot в k8s: Xmx=лимиту пода, а под всё равно OOMKilled

Сообщение nullssh6031 »

Ещё момент про Metaspace: если у тебя много классов (Spring, Hibernate генерят прокси), то при дефолтном -XX:MaxMetaspaceSize unlimited Metaspace тихо растёт и в итоге OOM от ядра прилетает не в heap, а в native. Ставь явно -XX:MaxMetaspaceSize=256m или 512m. Тогда хотя бы OOMError будет выброшен самой JVM с нормальным stack trace, а не молчаливый SIGKILL от k8s.
👍3 ❤️ 🔥 😄2 🤔
Аватара пользователя
omegaai1991
Сообщения: 21
Зарегистрирован: Вт май 12, 2026 9:35 pm

Re: Spring Boot в k8s: Xmx=лимиту пода, а под всё равно OOMKilled

Сообщение omegaai1991 »

Для диагностики в k8s удобно смотреть не на jvm heap, а на RSS процесса: kubectl exec <pod> -- cat /proc/1/status | grep VmRSS. Если RSS кратно больше Xmx — это подтверждение нативного оверхеда. Ещё полезно включить -Xlog:gc*:stdout и смотреть, не ли GC-паузы прямо перед OOMKill — иногда под OOMKill попадает не по памяти а по liveness probe таймауту во время Full GC.
👍1 ❤️ 🔥1 😄2 🤔
Ответить
Поделиться темой: ✈ Telegram VK

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость