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

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

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

Сообщение Austkin »

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

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

Сообщение nerd_max »

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

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

Сообщение cudauser »

А сколько закладывать на этот non-heap?
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
sleepypanic
Сообщения: 71
Зарегистрирован: 11 май 2026, 01:26

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

Сообщение sleepypanic »

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

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

Сообщение svelte88 »

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

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

Сообщение torchlover »

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

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

Сообщение asyncmonk »

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

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

Сообщение timur12 »

✔ Лучший ответ — сформирован автоматически
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 😄 🤔
Аватара пользователя
svelte88
Сообщения: 63
Зарегистрирован: 12 май 2026, 11:49

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

Сообщение svelte88 »

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

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

Сообщение duel »

Для диагностики в 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
Похожие запросы: что такое kubernetes и зачем он нуженкак посмотреть сколько памяти занято в linuxчем отличается deployment от pod в kubernetes простыми словамичто такое service в kubernetes и как поды находят друг другаrequests и limits в kubernetes как правильно задать ресурсы подуkubernetes pod crashloopbackoff почему падает

Вернуться в «DevOps и CI/CD»

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

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