Skip to content

/flags/java/java-xmx-max-heap-size

java -Xmx: set the maximum heap size (and fix OutOfMemoryError: Java heap space)

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · openjdk version "17.0.20.1" 2026-08-18updated
tool
Java
command
java
flag
-Xmx<size>
default
1/4 of physical memory (JVM ergonomics) when not set

java -Xmx512m -jar app.jar caps the Java heap at 512 MiB. When the program needs more heap than that, the JVM throws java.lang.OutOfMemoryError: Java heap space. Without -Xmx the JVM chooses the limit itself, by default one quarter of the machine's physical memory. The value takes a unit suffix: k/K, m/M or g/G; a number without a suffix means bytes. The equivalent long option is -XX:MaxHeapSize=<size>.

Setting it and hitting it

bash
cat > Mem.java <<'EOF'
public class Mem {
    public static void main(String[] args) {
        long max = Runtime.getRuntime().maxMemory() / (1024 * 1024);
        System.out.println("max heap (MiB): " + (max > 1000 ? "more than 1000" : String.valueOf(max)));
        if (args.length > 0) {
            java.util.List<byte[]> keep = new java.util.ArrayList<>();
            while (true) keep.add(new byte[1024 * 1024]);
        }
    }
}
EOF
echo "== default"
java Mem.java
echo "== -Xmx64m"
java -Xmx64m Mem.java
java -Xmx64m -XX:+PrintFlagsFinal -version 2>/dev/null | grep -E ' MaxHeapSize ' | awk '{print $2, $3, $4}'
echo "== -Xmx64m, filling the heap"
java -Xmx64m Mem.java fill; echo "exit: $?"
echo "== -Xmx64 (no unit = bytes)"
java -Xmx64 Mem.java; echo "exit: $?"

Output

== default
max heap (MiB): more than 1000
== -Xmx64m
max heap (MiB): 64
MaxHeapSize = 67108864
== -Xmx64m, filling the heap
max heap (MiB): 64
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at Mem.main(Mem.java:7)
exit: 1
== -Xmx64 (no unit = bytes)
Error occurred during initialization of VM
Too small maximum heap
exit: 1

With -Xmx64m the JVM reports a 64 MiB maximum (MaxHeapSize = 67108864 bytes), and the program that keeps allocating dies with OutOfMemoryError: Java heap space and exit code 1. Forgetting the unit asks for 64 bytes, which the JVM refuses at start-up with Too small maximum heap.

OptionWhat it setsNotes
-Xmx<size>Maximum heap sizeSame as -XX:MaxHeapSize
-Xms<size>Initial heap sizeSet equal to -Xmx on servers to avoid resizing
-XX:MaxRAMPercentage=<pct>Maximum heap as a percentage of available memoryContainer-friendly; ignored if -Xmx is set
-XX:InitialRAMPercentage=<pct>Initial heap as a percentagePairs with MaxRAMPercentage
-Xss<size>Thread stack sizeFor StackOverflowError, not heap problems
-XX:MaxMetaspaceSize=<size>Limit for class metadataOutOfMemoryError: Metaspace
-XX:+HeapDumpOnOutOfMemoryErrorWrite an .hprof heap dump when the heap runs outAnalyse it with a heap analyser to find the leak

Where to put it

bash
java -Xmx2g -jar app.jar                          # command line (before -jar or the class name)
JAVA_TOOL_OPTIONS="-Xmx2g" java -jar app.jar      # environment, picked up by every JVM
java -XX:MaxRAMPercentage=75 -jar app.jar         # containers: 75% of the memory limit
./gradlew build -Dorg.gradle.jvmargs=-Xmx2g       # Gradle daemon (or org.gradle.jvmargs in gradle.properties)
MAVEN_OPTS="-Xmx2g" mvn package                   # Maven

JVM options must come before the main class or -jar app.jar. Anything after it is passed to your program as an argument; a typo there turns into an unexpected argument, while a typo before it can be read as the class name and end in Could not find or load main class.

Diagnosing heap problems

  • OutOfMemoryError: Java heap space with a small -Xmx and a legitimate workload: raise -Xmx.
  • The same error with any -Xmx: probably a leak (a growing cache or collection); a bigger heap only delays it. Run with -XX:+HeapDumpOnOutOfMemoryError and inspect the dump.
  • GC overhead limit exceeded: the JVM spends almost all its time in garbage collection with very little reclaimed, another sign that the heap is nearly full.
  • The process is killed by the OS or container (exit 137 on Linux) without an OutOfMemoryError: total memory, not the heap, exceeded the limit; lower -Xmx or raise the container limit.

FAQ

What is the default maximum heap size in Java?

When -Xmx is not set, the JVM ergonomics pick one quarter of the physical memory as the maximum heap, as described in the Java garbage collection tuning guide. In containers, recent JVMs use the container memory limit instead of the host memory.

Should -Xms be equal to -Xmx?

For servers with a known memory budget, setting both to the same value avoids heap resizing pauses and makes the memory use predictable. For desktop tools and short-lived programs, leave -Xms unset so the JVM starts small.

Does -Xmx limit the total memory of the java process?

No. It limits only the Java heap. Metaspace, thread stacks, the code cache, direct buffers and the JVM itself use memory on top of it, so a container needs headroom above the -Xmx value.

Sources