0Pricing
Java Academy · Lesson

Common JVM Tuning Flags

Heap, GC, and JIT options.

Common JVM Tuning Flags is a free Java Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Java Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Why Tune the JVM?

The JVM has sensible defaults, but for demanding services you sometimes adjust heap size, the garbage collector, and JIT behavior.

Tuning is a last step: profile first, fix the code, then reach for flags only when measurements justify them.

Heap Size: -Xms and -Xmx

The two most common flags set heap bounds:

  • -Xms — initial heap size.
  • -Xmx — maximum heap size.

Example: java -Xms512m -Xmx2g MyApp. Setting -Xms equal to -Xmx avoids resize pauses in long-running servers.

Reading the Defaults

You can ask the JVM what it chose. Runtime exposes the current heap numbers, and -XX:+PrintFlagsFinal dumps every flag's effective value.

The example prints the running JVM's memory limits.

public class Main {
    public static void main(String[] args) {
        Runtime rt = Runtime.getRuntime();
        long mb = 1024 * 1024;
        System.out.println("Max heap (Xmx): " + (rt.maxMemory() / mb) + " MB");
        System.out.println("Total heap now: " + (rt.totalMemory() / mb) + " MB");
        System.out.println("Free in heap: " + (rt.freeMemory() / mb) + " MB");
        System.out.println("Available cores: " + rt.availableProcessors());
    }
}

Choosing a Collector

Modern JDKs offer several garbage collectors:

  • -XX:+UseG1GC — the default; balanced, region-based.
  • -XX:+UseZGC — ultra-low pause, large heaps.
  • -XX:+UseParallelGC — max throughput, longer pauses.
  • -XX:+UseSerialGC — single-threaded, tiny apps and containers.

G1 Pause Target

G1 is a pause-time-oriented collector. You give it a goal and it tries to meet it:

  • -XX:MaxGCPauseMillis=200 asks G1 to keep pauses near 200 ms.

It is a soft target, not a guarantee. Setting it too low forces frequent small collections and can hurt throughput.

ZGC for Low Latency

When pause times must stay sub-millisecond even on multi-gigabyte heaps, use ZGC with -XX:+UseZGC.

It does most of its work concurrently with your application threads. The trade-off is some extra CPU and memory overhead compared with G1. Ideal for latency-sensitive services.

GC Logging

To tune GC you must see it. Enable unified logging:

  • -Xlog:gc*:file=gc.log:time,uptime,level,tags

This records every collection with timestamps and durations. Feed the log into a viewer (or JMC/JFR) to spot long or frequent pauses before changing any flag.

Containers and CPU

Inside containers the JVM reads cgroup limits. By default it uses a fraction of the memory limit for the heap.

  • -XX:MaxRAMPercentage=75.0 sets heap as a percent of container memory.
  • -XX:ActiveProcessorCount=N overrides detected CPU count.

This avoids over-committing memory the orchestrator will then kill.

JIT and Diagnostics Flags

A few more useful flags:

  • -XX:+HeapDumpOnOutOfMemoryError — dump heap on OOM for post-mortem analysis.
  • -XX:HeapDumpPath=/tmp — where to write it.
  • -XX:+PrintCompilation — see JIT compilation activity.

These cost little and pay off when something goes wrong.

Tuning Discipline

Golden rules for flags:

  • Change one flag at a time and re-measure against a baseline.
  • Do not copy flags blindly from blog posts — they may target an old JVM.
  • Most apps need only -Xmx and maybe a collector choice; the defaults are good.

Metaspace and Threads

Heap is not the only memory region:

  • -XX:MaxMetaspaceSize caps class metadata space; without it a class-loading leak can exhaust native memory.
  • -Xss sets per-thread stack size; lower it if you run very many threads, raise it for deep recursion.

These rarely need tuning, but knowing they exist helps when native memory, not heap, is the problem.

Quick Check

What do the -Xms and -Xmx flags control?

Recap

The flags worth knowing:

  • -Xms / -Xmx bound the heap.
  • Pick a collector: G1 (default), ZGC (low pause), Parallel (throughput).
  • Set -XX:MaxGCPauseMillis for G1; enable -Xlog:gc* to observe.
  • Use MaxRAMPercentage in containers and HeapDumpOnOutOfMemoryError for safety.
  • Change one flag at a time and measure.

Frequently asked questions

Is the “Common JVM Tuning Flags” lesson free?

Yes — the full text of “Common JVM Tuning Flags” is free to read here on the web, and the Java Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Java Academy course, upgrade to CoddyKit PRO.

What will I learn in “Common JVM Tuning Flags”?

Heap, GC, and JIT options. You practise Java Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Java Academy?

No prior experience is required. Java Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Common JVM Tuning Flags” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Java Academy lesson?

Yes. Every Java Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Identifying Bottlenecks
  2. Java Flight Recorder
  3. Analyzing with JDK Mission Control
  4. Common JVM Tuning Flags
← Back to Java Academy