-Xms and -Xmx in Java: How to Speed Up the JVM Without Killing the Server

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Why Is Your Java Program "Slow" and How to Fix It with -Xms and -Xmx?

\n

Have you ever launched a Java application that worked like clockwork at first, but after an hour started to "slow down," and then crashed with an OutOfMemoryError? Or, conversely, the server consumed all RAM but only used 20%? Most likely, the issue lies in the heap settings — -Xms and -Xmx. These two parameters are the key to balancing JVM performance and stability.

\n

In this article, we'll break down what -Xms and -Xmx actually do, how to choose the right values for your application, and show code examples to help you avoid common mistakes. Ready? Let's go!

\n\n

What are -Xms and -Xmx? Understanding JVM Parameters

\n

In short: -Xms sets the initial heap size, and -Xmx sets the maximum. But the devil, as always, is in the details.

\n
    \n
  • -Xms (Initial Heap Size) — the amount of memory the JVM reserves at startup. If you specify -Xms512m, the virtual machine immediately allocates 512 MB.
  • \n
  • -Xmx (Maximum Heap Size) — the upper limit to which the heap can grow. For example, -Xmx4g means the JVM will never use more than 4 GB.
  • \n
\n

Why is this important? The JVM is not a "rubber" environment. If you allocate too little initial memory (-Xms), the program will frequently call the garbage collector (GC) to expand the heap, which slows down performance. If you set -Xmx too high, you risk consuming all system memory, causing the OS to start swapping — performance will drop dramatically.

\n\n

Practical Example: How to Configure Memory for a Java Application

\n

Let's imagine we have a Spring Boot web server processing user requests. Without JVM settings, it will use default values (depending on the Java version and RAM size), which often leads to problems.

\n

Here is simple code that demonstrates how to check the current heap parameters:

\n
public class MemoryCheck {\n    public static void main(String[] args) {\n        Runtime runtime = Runtime.getRuntime();\n        long maxMemory = runtime.maxMemory(); // -Xmx\n        long initialMemory = runtime.totalMemory(); // current heap size (may be close to -Xms)\n        long freeMemory = runtime.freeMemory();\n\n        System.out.println("Max memory (-Xmx): " + maxMemory / (1024 * 1024) + " MB");\n        System.out.println("Current heap size: " + initialMemory / (1024 * 1024) + " MB");\n        System.out.println("Free memory: " + freeMemory / (1024 * 1024) + " MB");\n    }\n}
\n

Run this code without flags — you'll see the default values. Now add the JVM arguments: -Xms256m -Xmx1g. The result will change drastically: the initial heap becomes 256 MB, and the maximum becomes 1 GB.

\n\n

How to Pass the Parameters?

\n

When launching from the command line:

\n
java -Xms256m -Xmx2g -jar myapp.jar
\n

In an IDE (IntelliJ IDEA, Eclipse) — in the run configuration settings. For Docker containers — via the JAVA_OPTS environment variable.

\n\n

Performance Optimization: How to Choose the Right Values

\n

The golden rule: -Xms should equal -Xmx for a production environment. Why? This prevents memory "jumps" and unnecessary garbage collector calls. The JVM won't waste time expanding the heap but will immediately get a fixed amount of memory.

\n

However, there are nuances:

\n
    \n
  • For web applications with high load, set -Xms and -Xmx to 70-80% of the server's available RAM. Leave the rest for the OS and other processes.
  • \n
  • For batch processors (batch jobs), you can set -Xms smaller if the application doesn't require a lot of memory immediately.

Blogs

Book Recommendations