What Are Xmx and Xms in Java?

-Xmx sets the maximum size of the Java heap, and -Xms sets its initial size. Both are flags passed to the java command, for example java -Xms2g -Xmx2g -jar app.jar. The heap is the memory region where the JVM stores every object your program creates and where the garbage collector reclaims space. If live objects need more than -Xmx, the JVM throws java.lang.OutOfMemoryError: Java heap space.

The names are not acronyms. The -X prefix marks a HotSpot option that is not part of the Java standard. A common reading is "ms" for memory start and "mx" for memory maximum. The flags are the same on Linux, Windows and macOS, and on every HotSpot-based JDK from Oracle, OpenJDK, Amazon Corretto and Eclipse Temurin.

Syntax and units

The size follows the flag directly, with no space and no equals sign. -Xmx 4g and -Xmx=4g are both errors.

FlagWhat it setsExampleRule
-Xms<size>Initial heap size-Xms512mA multiple of 1024, greater than 1 MB
-Xmx<size>Maximum heap size-Xmx4gA multiple of 1024, greater than 2 MB, at least -Xms
-Xmn<size>Size of the young generation, where new objects are created-Xmn1gLeave unset with the G1 collector, which sizes it adaptively
-Xss<size>Stack size per thread-Xss512kDefault is 1 MB on 64-bit Linux and Windows
-XX:MaxRAMPercentage=<n>Maximum heap as a percentage of available memory-XX:MaxRAMPercentage=75.0Container-friendly alternative to -Xmx
-XX:InitialRAMPercentage=<n>Initial heap as a percentage-XX:InitialRAMPercentage=75.0Alternative to -Xms

The unit suffix is k or K for kilobytes, m or M for megabytes and g or G for gigabytes. A number with no suffix is bytes. The units are binary, so 1g equals 1024m. Searches for "xmnx" are usually a misspelling of -Xmn or -Xmx; there is no flag by that name.

Defaults when you set nothing

On a machine or container with 2 GB or more of memory, HotSpot picks the maximum heap as one quarter of physical memory and the initial heap as one sixty-fourth. An 8 GB container with no flags therefore gets a 2 GB maximum heap and a 128 MB initial heap. From JDK 10, and from update 191 of JDK 8, physical memory means the container's cgroup limit rather than the host's RAM.

You can print the values the JVM has chosen without running your application.

java -XX:+PrintFlagsFinal -version | grep -Ei "MaxHeapSize|InitialHeapSize|MaxRAMPercentage"

For a running process, jcmd <pid> VM.flags prints the same values, and Runtime.getRuntime().maxMemory() returns the maximum heap from inside the program.

Xmx versus Xms: what each one changes

-Xms (initial)-Xmx (maximum)
Set too lowThe JVM grows the heap in steps after startup, and each step involves a garbage collectionOutOfMemoryError once live data exceeds the limit
Set too highMemory is committed that the application never usesHeap plus non-heap memory exceed the container limit, and the kernel kills the process with exit code 137
Typical value for a serviceEqual to -Xmx50 to 75 percent of the container's memory limit

The exit code 137 case is worse than the Java exception. There is no stack trace, no heap dump, and the log ends mid-line. It happens because -Xmx limits only the heap. Thread stacks, class metadata (metaspace), the JIT code cache, garbage collector data and direct byte buffers for network I/O all live outside it.

Setting -Xms equal to -Xmx is the usual choice for a long-running service. The heap never resizes, so there are no resize-triggered collections and the memory use is predictable from the first second. For a short command-line tool, leaving -Xms at its default lets the JVM start with a small heap and finish before it ever grows.

Worked example: sizing a service

Suppose a Spring Boot API runs in a container with a 4 GB memory limit and a pool of 200 request threads. The heap is sized by subtracting the non-heap budget from the limit.

  1. Thread stacks. 200 threads x 1 MB = 200 MB. Setting -Xss512k halves that if the stacks are shallow.
  2. Metaspace and code cache. A typical Spring application uses 100 to 200 MB of class metadata and up to 240 MB of compiled code.
  3. Direct buffers and collector data. Allow about 200 MB for network buffers and the collector's own structures.
  4. Total non-heap. Roughly 700 MB to 1 GB. Round up to 1 GB.
  5. Heap. 4 GB minus 1 GB leaves 3 GB. Set -Xms and -Xmx both to 3g.
java -Xms3g -Xmx3g -Xss512k -XX:+UseG1GC -Xlog:gc:file=/var/log/api/gc.log -jar api.jar

The percentage form gives the same result and follows the limit if the container is resized.

java -XX:InitialRAMPercentage=75.0 -XX:MaxRAMPercentage=75.0 -jar api.jar

Verify under a load test by reading the garbage collection log. After a full collection, the live data should occupy about a third to a half of the heap. If it occupies more than 70 percent, the heap is too small and collections will run constantly. If it occupies under 20 percent, memory is being wasted and a smaller container would do.

Where to put the flags

On the command line, the flags go before -jar. In a container image, the environment variable JAVA_TOOL_OPTIONS is read by every JVM at startup, so JAVA_TOOL_OPTIONS="-Xms3g -Xmx3g" works without editing the start command. Tomcat reads CATALINA_OPTS, and most application servers have an equivalent. Maven and Gradle builds read MAVEN_OPTS and org.gradle.jvmargs respectively.

Key Takeaways

  • -Xms is the initial heap and -Xmx is the maximum heap. Write them as -Xms2g -Xmx2g, with no space or equals sign.
  • Units are k, m and g, and the values are binary, so 1g is 1024m.
  • With no flags, the maximum heap is one quarter of the container's memory and the initial heap is one sixty-fourth.
  • For a service, set both flags to the same value, at 50 to 75 percent of the container limit, and leave the rest for stacks, metaspace and buffers.

Grokking System Design Fundamentals covers the memory and capacity estimates that this sizing exercise is part of.

Grokking the System Design Interview shows where JVM services sit in a full system design answer.

Grokking Multithreading and Concurrency for Coding Interviews explains the thread pools whose stacks appear in the non-heap budget above.

TAGS
System Design Interview
CONTRIBUTOR
Arslan Ahmad
Arslan Ahmad
ex-FAANG engineering manager and author or Grokking series.

GET YOUR FREE

Coding Questions Catalog

Design Gurus Newsletter - Latest from our Blog
Boost your coding skills with our essential coding questions catalog.
Take a step towards a better tech career now!
Explore Answers
What is the role of a system designer?
What to Expect in the Roblox System Design Interview
Roblox design rounds run gaming physics: real-time multiplayer state, matchmaking, virtual economies, and safety systems at platform scale, with latency and fault tolerance graded hard.
What is Phase 1 Apple interview?
Which skill is best for interview?
What is positive about Amazon?
What does Coinbase ask for?
Related Courses
New
Grokking the AI System Design Interview course cover
Grokking the AI System Design Interview
Learn to design AI systems the way interviewers expect: classic ML products, LLM and RAG architectures, and agentic systems, all through the lens of the system design interview.
4.6
(3,192 learners)
Discounted price for Your Region

$123

Grokking the Coding Interview: Patterns for Coding Questions course cover
Grokking the Coding Interview: Patterns for Coding Questions
The 24 essential patterns behind every coding interview question. Available in Java, Python, JavaScript, C++, C#, and Go. The most comprehensive coding interview course with 543 lessons. A smarter alternative to grinding LeetCode.
4.6
Discounted price for Your Region

$197

Grokking Modern AI Fundamentals course cover
Grokking Modern AI Fundamentals
Master the fundamentals of AI today to lead the tech revolution of tomorrow.
4.1
Discounted price for Your Region

$72

Design Gurus logo
One-Stop Portal For Tech Interviews.
Copyright © 2026 Design Gurus, LLC. All rights reserved.