Java on Kubernetes · open source · v0.1
Will your JVM fit in its Kubernetes container?
jvm-fit is a free, open-source CLI that reads your Kubernetes manifests, Helm charts or Kustomize overlays together with the JVM flags in them, and tells you before deploy whether the JVM will fit in the container. It explains why a Java pod gets OOMKilled with a half-empty heap, and what to change.
OOMKilled, and the heap is only 60% full
Java in Kubernetes often breaks even when everything looks configured. The heap takes almost the whole memory limit and non-heap memory (metaspace, thread stacks, code cache, direct buffers) does not fit. A CPU limit below two cores makes the JVM pick SerialGC. With no heap flags the heap is 25% of the limit and the rest sits idle. jvm-fit finds these from the manifest, before the pod ever starts.
What jvm-fit does
Go · Apache-2.0 licence · version 0.1.0
Memory budget
Adds the maximum heap and a non-heap estimate, compares them with the container limit and shows by how much you are over.
12 rules
No memory limit, -Xmx at or above the limit, MaxRAMPercentage above 80, default 25% heap, container support switched off, request below limit and more.
CPU limits and GC choice
Warns when the JVM will silently pick SerialGC: fewer than 2 CPUs or less than 1792Mi of memory.
Startup probes
Flags a liveness probe that can kill a slow-starting JVM because there is no startup probe.
A fix for every finding
Each finding comes with concrete flags and limits to use, and an explain command says why it matters.
Manifests, Helm, Kustomize
Scans plain YAML, renders Helm charts with your values files and reads Kustomize overlays.
Verified on real JDKs
On every CI run a test starts JDK 11, 17 and 21 in Docker and fails if the model predicts something else.
Built for CI
Text, JSON or SARIF output and a GitHub Action that annotates pull requests.
Quick start
go install github.com/andronaft/jvm-fit/cmd/jvm-fit@latest
jvm-fit scan ./k8s/ # files and directories
jvm-fit scan ./charts/payments -f values.yaml # Helm chart
jvm-fit scan ./k8s/overlays/prod # Kustomize overlay
jvm-fit explain JVM007 # why it matters, how to fix it
Questions
Why is my Java pod OOMKilled when the heap is not full?
The container limit covers all JVM memory, not only the heap. Metaspace, thread stacks, code cache and direct buffers live outside the heap. If -Xmx or MaxRAMPercentage leaves too little room for them, the kernel kills the pod while the heap still has space.
What should MaxRAMPercentage be in Kubernetes?
There is no single number, because non-heap memory does not shrink with the limit. jvm-fit flags values above 80 and computes a value that leaves room for a non-heap estimate, which you can set yourself.
Why does my JVM use SerialGC in a container?
HotSpot picks SerialGC when it sees fewer than 2 CPUs or less than about 1792Mi of memory. A CPU limit below 2 cores is enough to trigger it, even on a large node.
Does jvm-fit need a running cluster?
No. It is a static check of manifests. It does not see real memory use and does not read live clusters yet; both are planned for v0.2 with Prometheus metrics.
How is it different from KRR or Goldilocks?
Those tools size containers from real usage. jvm-fit checks that the JVM flags fit the limit you chose, so they work well together.
Is it free?
Yes, open source under the Apache 2.0 licence.
Read more
How and why I built it, and my other tools.