DevOps

JVM Heap Sizing Calculator

Size a JVM heap against a container memory limit, accounting for metaspace, thread stacks, code cache and direct buffers, and avoid the off-heap overhead that causes container OOM kills.

Last reviewed by the Radiatus Cloud team

Sizing appears here.

Want this automated for your stack?

We build CI/CD, Kubernetes & IaC pipelines that scale.

Talk to an engineer

The heap is not the whole footprint

A JVM configured with a two gigabyte heap in a two gigabyte container is killed by the kernel, reliably, and the logs show no Java error because the process was terminated from outside. Beyond the heap, the JVM allocates metaspace for class metadata, a stack per thread, a code cache for JIT output, garbage collector structures, direct byte buffers used by NIO and most network libraries, and the native memory the runtime itself needs. That overhead is commonly twenty five to forty percent of the heap size, and it is invisible to every heap based tuning guide.

Container awareness and its limits

Modern JVMs read the cgroup memory limit and default MaxRAMPercentage to twenty five percent, which is safe and wasteful. Raising it to sixty or seventy percent is usually right for a service, leaving room for the off-heap components. Using MaxRAMPercentage rather than a fixed Xmx means the same image behaves correctly when the limit changes, which matters in Kubernetes where limits are edited far more often than JVM flags.

Choosing a collector

G1 is the default from Java 9 and the right answer for most services. ZGC and Shenandoah are concurrent collectors with sub millisecond pauses that matter above roughly four gigabytes of heap or where tail latency is the product. Parallel GC still produces the best raw throughput for batch work where a pause of a second is irrelevant. Serial GC is correct for a small container with a single core, where the others spend more on coordination than they save.

Related tools

Frequently Asked Questions

Why does my container get OOM killed with plenty of heap free?

Because the kernel counts the whole process, not the heap. Metaspace, thread stacks, code cache, direct buffers and GC structures sit outside the heap and commonly add 25 to 40 percent. A heap sized to the container limit is a guaranteed kill.

Should I use Xmx or MaxRAMPercentage?

MaxRAMPercentage in a container, because it adapts when the memory limit changes and the same image then behaves correctly everywhere. A fixed Xmx has to be edited in lockstep with the Kubernetes limit, and one of the two is always forgotten.

How much memory does each thread cost?

One megabyte of reserved stack by default on 64 bit platforms, though only the touched pages are resident. A service with 400 threads reserves 400 MB. Thread-per-request frameworks with large pools are the usual reason off-heap memory is larger than expected.

Which garbage collector should I choose?

G1 for most services. ZGC or Shenandoah above about 4 GB of heap or where tail latency matters more than throughput. Parallel for batch work where pauses are irrelevant. Serial for a small single core container, where the parallel collectors cost more in coordination than they return.

Should heap request and limit be equal in Kubernetes?

For a JVM, yes. Memory is not compressible, so exceeding the limit means a kill rather than throttling. Setting request equal to limit gives the pod the Guaranteed QoS class and stops the scheduler overcommitting the node.

Privacy & Security

Everything runs in your browser; nothing is uploaded.

Data: None
Client-side-Side
Active
v1.0

How to Use

Enter the container memory limit and workload characteristics to get heap and GC flags.

Disclaimer: This tool is provided "as is" without warranty of any kind. Results are for educational and utility purposes.