JVM Tuning and Tools

Common JVM Flags

FlagMeaning
-Xms1g -Xmx1ginitial and max heap (same value avoids resizing)
-XX:MaxRAMPercentage=75heap as % of container memory (Docker/Kubernetes)
-Xss512kthread stack size
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/dumpswrite a heap dump when OOM happens
-Xlog:gc*:file=gc.logGC log to a file
-XX:+UseZGCchoose a collector

JDK Tools

ToolUse
jpslist running Java processes
jcmd <pid> GC.heap_info, Thread.print, GC.heap_dumpSwiss-army knife
jstack <pid>thread dump (find deadlocks, stuck threads)
jstat -gc <pid> 1000GC statistics every second
JFR + JDK Mission Controllow-overhead profiling in production
VisualVM, Eclipse MATheap dump analysis (find leaks)

Example

jcmd 4321 GC.heap_info

Example output

4321:
 garbage-first heap   total 524288K, used 187340K
  region size 1024K, 52 young (53248K), 6 survivors (6144K)
 Metaspace       used 61234K, committed 62016K, reserved 1114112K

Reading Runtime Info in Code

Example

Runtime and ManagementFactory expose JVM details. (Exact memory numbers vary by machine, so this prints only stable facts.)

import java.lang.management.*;

public class Main {
    public static void main(String[] args) {
        Runtime rt = Runtime.getRuntime();
        System.out.println("Java version: " + Runtime.version().feature());
        System.out.println("Processors > 0: " + (rt.availableProcessors() > 0));
        System.out.println("max >= total >= free: " + (rt.maxMemory() >= rt.totalMemory() && rt.totalMemory() >= rt.freeMemory()));

        RuntimeMXBean jvm = ManagementFactory.getRuntimeMXBean();
        System.out.println("VM vendor present: " + !jvm.getVmVendor().isEmpty());
        ThreadMXBean threads = ManagementFactory.getThreadMXBean();
        System.out.println("Live threads >= 1: " + (threads.getThreadCount() >= 1));
    }
}

Output

Java version: 21
Processors > 0: true
max >= total >= free: true
VM vendor present: true
Live threads >= 1: true