← Back

Concepts

Why HotSpot groups JVM flags into domains, categories, and subcategories—and what each group is for.

This reference explains why each taxonomy group exists and which JVM flags operators reach for most often. Taxonomy is defined in catalog-taxonomy.json (6 domains, 15 categories, 88 subcategories) and shared across java-8.jsonjava-25.json. Flag examples below come from the Java 25 catalog; availability varies by release—use the interactive graph or evolution view for other versions. See methodology for how catalogs are built and verified.

Memory & layout

Every Java object lives in the heap; class metadata in metaspace; each thread has a stack. Sizing these regions is usually the first production tuning step. Too small causes OutOfMemoryError or excessive GC; too large wastes RAM and can lengthen pauses. Layout flags (compressed pointers, alignment) trade address space for density on 64-bit JVMs.

Heap

The object heap is where instances and arrays reside. Capacity flags set hard limits; generational flags split young vs old generations for copying collectors. Separate from choosing which GC algorithm runs (see Garbage Collection).

Direct Memory

Direct byte buffers allocate outside the object heap in native memory. NIO, Netty, and many frameworks use them heavily. The limit is separate from -Xmx and can cause OutOfMemoryError: Direct buffer memory.

Heap Layout & Footprint

Layout flags control compressed class pointers, heap region geometry, and overall footprint. They interact with object reference compression and maximum heap addressability on 64-bit VMs.

Heap Resize Heuristics

Unless min equals max, the JVM can grow or shrink the heap based on utilization heuristics. Resize causes allocation stalls and RSS changes visible to container limits.

Heap Size

Heap size flags set the minimum and maximum memory the JVM may use for Java objects. Setting -Xms equal to -Xmx avoids resize work during steady state but commits memory up front. Ergonomics on server-class machines derive defaults from available RAM unless you override them.

Large Pages

Huge pages (2 MB or 1 GB) reduce TLB misses for very large, long-running heaps. Requires OS configuration (hugetlbfs, vm.nr_hugepages) and often reserving memory at boot.

NUMA

On multi-socket hosts, NUMA policies place heap pages near the CPU allocating them. Interleaving spreads memory across nodes; local allocation reduces remote memory access latency.

RAM-Based Sizing

On server-class machines the JVM picks default heap fractions from physical memory (MaxRAMPercentage, ergonomics). Container-aware versions read cgroup limits instead.

Survivor Spaces

Survivor spaces buffer objects between Eden and the old generation. Copying collectors move live objects between From and To survivor spaces during minor GC. Too-small survivors force premature promotion to old gen.

Tenured Generation

The tenured (old) generation stores long-lived objects. When it fills, a major or full collection runs—often the dominant pause for generational collectors. Sizing old gen relative to young gen affects promotion failure and fragmentation.

Tenuring & Promotion

Objects survive a number of minor collections before promotion. The tenuring threshold and survivor copying policy filter short-lived garbage from long-lived data. Tuning reduces unnecessary promotion and old-gen pressure.

Young Generation

The young generation holds newly allocated objects. Minor collections copy survivors to tenured space or another survivor space. A young gen that is too small causes frequent minor GC; too large delays major collections and can waste copying work.

Metaspace

Since Java 8, class metadata lives in native metaspace—not the Java heap and not PermGen. Frameworks that generate many classes (Spring, Hibernate, agents) need metaspace caps and reclaim policy.

Large Pages

Large pages for metadata reduce TLB pressure in class-heavy JVMs (big Spring apps, application servers with many deployments).

Metaspace Sizing

Metaspace grows with loaded classes. Without a cap, class-loader leaks exhaust native memory. Set a max to fail fast; initial size avoids repeated expansion during startup.

Reclaim Policy

When classes unload, metaspace chunks may return to the OS or stay reserved. Reclaim policy affects RSS after redeployments and framework hot-reload scenarios.

Object Layout

Object headers, reference width, and compression determine how many objects fit per gigabyte. These are usually left at defaults unless you run very large heaps or specialized benchmarks.

Alignment

Objects align to 8-byte (or wider) boundaries for atomic access and SIMD. Alignment padding is invisible in source but shows up in heap dumps as overhead.

Compression

Compressed oops and compressed class pointers shrink references and headers on 64-bit JVMs. Disabling compression is rare and increases heap footprint; required only for heaps above roughly 32 GB with compressed oops or specific benchmarks.

Stack

Each thread stack holds frames for Java calls and native transitions. Deep recursion or heavy JNI needs larger -Xss; thousands of threads need smaller stacks to fit in RAM.

FPU

x86 FPU/SSE mode flags matter mainly for legacy numeric code and strict FP semantics.

General Stack

Miscellaneous stack-related VM behavior not covered by OSR or trace generation.

On-Stack Replacement

On-stack replacement compiles a method while an invocation is still active on the stack. OSR bails out hot loops in interpreted code without waiting for method exit.

Stack Sizing

Each platform thread consumes a fixed or growable stack. Default is often 1 MB on Linux. Deep XML/JSON parsing, recursion, or Scala implicit chains may need more; massive thread pools need less per thread to fit container memory.

Stack Traces

Controls how stack traces are collected and printed on errors, and hidden frames in reflective/agent stacks.

Garbage collection

Garbage collectors reclaim unreachable objects so applications rarely call free. Collector choice dominates latency profiles: G1 balances throughput and pauses; ZGC and Shenandoah target sub-millisecond pauses on large heaps; Parallel optimizes batch throughput. Tuning flags adjust worker threads, region sizes, pause goals, and incremental steps.

Garbage Collection

One category holds all collector implementations and cross-cutting GC mechanics: allocation, references, explicit GC, logging, and legacy CMS/Serial options.

Adaptive Size Policy

Adaptive sizing resizes generations to meet pause or throughput goals automatically. Common with Parallel GC and older ergonomics.

Allocation

Thread-local allocation buffers (TLABs) and fast-path allocation reduce synchronization on hot allocation sites. Failure handling triggers GC or expansion.

CMS

Concurrent Mark Sweep was the low-pause collector before G1. Removed in recent JDKs but flags remain in older catalogs. Avoid for new deployments.

Card Table

Write barriers mark card tables when references cross regions or generations, enabling incremental old-gen scanning without scanning the entire heap.

Default

Selects which garbage collector the JVM uses. This is the highest-impact GC decision: G1 is default on many server releases; ZGC and Shenandoah target low latency; Parallel targets throughput; Serial suits small heaps.

Explicit GC

System.gc() and Runtime.gc() request a collection. Libraries sometimes call them defensively; disabling avoids full STW surprises but may hide memory pressure.

Free List & Compaction

CMS and similar collectors used free lists for old-gen blocks. Fragmentation and promotion failures were common tuning pain points.

Full GC Behavior

Full collections compact the entire heap and collect all generations. Triggers include metaspace pressure, promotion failure, and diagnostic requests.

G1 Tuning

G1 divides the heap into regions and collects incrementally toward a pause-time goal. Tuning sets region size, IHOP (initiating heap occupancy), mixed GC cadence, and humongous object handling.

GC Locker

JNI critical regions can pin objects and delay GC (GC Locker). Long critical sections cause "GC locker" stalls visible in logs.

GC Overhead & Time Limits

Limits how much wall-clock time may be spent in GC before throwing OutOfMemoryError: GC overhead limit exceeded.

GC Threads

Parallel and concurrent collectors use dedicated threads. Count should align with container CPU quota—not always equal to host cores.

General GC

Cross-collector switches: ergonomics, heap occupancy reporting, and global behaviors that apply regardless of G1 vs ZGC.

Legacy Heap Sizing

Pre-G1 flags for fixed young/old sizes persist for migration scripts. Prefer G1 region tuning or percentage-based sizing on new systems.

Logging GC

GC logs are essential for pause analysis. Prefer unified logging -Xlog:gc* on modern JDKs over legacy PrintGCDetails.

Mark Stack

During marking, the GC traces object graphs using mark stacks. Depth and chunk sizing affect pause times and peak native memory during GC.

NMethod Sweep

Compiled methods (nmethods) interact with GC sweeps when code cache pressure and unloading coincide.

ParallelGC

Parallel GC uses multiple threads for young and old collections. Best for batch workloads tolerating longer pauses in exchange for raw throughput.

References

Soft, weak, and phantom references and finalization queues are processed during GC. Mis-tuning can delay cleanup of class loaders or off-heap wrappers.

SerialGC

Serial GC runs stop-the-world collections on one thread. Suitable for small heaps and client-style apps with minimal footprint.

Shenandoah

Shenandoah is another low-pause concurrent collector with Brooks pointers. Popular where ZGC is unavailable; tuning includes heuristics and uncommit delay.

String Deduplication

G1 can deduplicate identical char[] backings for Strings during GC, saving heap on text-heavy workloads (logs, XML, JSON).

ZGC

ZGC performs most work concurrently with load barriers. Aims for sub-millisecond pauses on multi-TB heaps. Requires recent JDK and often larger CPU budget for concurrent workers.

Execution & code

HotSpot starts in the interpreter, profiles hot methods, then compiles them to native code in the code cache. JIT flags control when compilation happens, how aggressively methods are inlined, and whether intrinsics replace JDK methods. Runtime flags cover JNI, signals, and fatal-error behavior on the execution path outside pure Java bytecode.

JIT Compiler

C1 (client) and C2 (server) compilers turn bytecode into machine code. Tiered mode uses both. Disabling compilation or limiting inlining is mainly for debugging, not production.

Compilation

Background compilation threads compile hot methods asynchronously. Queue backlog means methods stay in slower tiers longer after warmup.

Escape Analysis

Escape analysis stack-allocates or scalar-replaces objects that do not escape a thread. Can eliminate locks on non-shared objects.

Execution Modes

Force interpreter-only or limit compilation for debugging miscompiled code or reproducing issues before C2 optimization.

Inlining

Inlining replaces callee invocations with copied bytecode, removing call overhead. Excessive inlining increases code size; too little leaves performance on the table.

Intrinsics

Intrinsics replace known methods (System.arraycopy, math, unsafe) with hand-tuned machine code.

Tiered Compilation

Tiered compilation uses interpreter → C1 → C2 progression. C1 profiles quickly; C2 optimizes aggressively. Disabling tiers is for troubleshooting only.

Code Cache

Compiled code is stored off-heap in the code cache. When full, the JVM stops compiling or sweeps old methods, which can cause sudden performance cliffs.

Code Cache Behavior

Sweeper reclaims dead nmethods. Behavior flags control unloading aggressiveness and interaction with GC.

Code Cache Sizing

Reserved and non-reserved code cache segments hold C1 and C2 code. Exhaustion triggers sweeps or disables compilation—watch for "CodeCache is full" in logs.

Runtime

Core VM services: parsing options, interpreter, JNI bridges, OS signals, and low-level memory-model barriers. Many flags are diagnostic or expert-only.

CLI & JVM Options

Startup parsing of -X, -XX, and advanced options. PrintFlagsFinal dumps effective values—essential when scripts set many flags.

Contended & Monitors

Biased locking, monitor inflation, and contended lock optimizations reduce synchronization overhead on hot locks.

Fatal Error & VM Output

On VM fatal errors, HotSpot writes hs_err_pid files and may heap-dump. Flags control detail level and default dump paths.

Interpreter

Template interpreter executes bytecode before compilation. Profiling counters here drive tier promotion decisions.

JNI

JNI transitions between Java and native code have cost and safepoint implications. Checking modes catch binding errors early in development.

Memory Model & Barriers

Barriers implementing the Java Memory Model for volatile, final, and atomic operations. Rarely tuned outside JVM development.

Object Initialization & Strings

Fast paths for object allocation, array copy, and string concatenation in the runtime.

Platform & Hardware

CPU feature detection (AVX, AES-NI), unaligned access, and vendor-specific paths.

Signals & OS Integration

Signal handlers for crash reporting (SIGSEGV), graceful shutdown, and thread dump on SIGQUIT (kill -3).

Symbols & Annotations

Symbol table and constant pool storage for classes and dynamic language support.

Tracing & Profiling

Low-level tracing hooks for profilers and diagnostic agents (JVMTI, DTrace where supported).

Classes & modules

Classes are loaded on demand, verified for bytecode safety, and optionally loaded from shared archives (CDS) for faster startup. Mis-tuned class loading shows up as long startup, metaspace growth, or ClassNotFoundException in modular applications.

Class Loading

Controls verification, shared archives, parallel loading, and tracing. CDS in particular cuts startup time for CLI tools and microservices.

Boot Class Loader

Bootstrap loader loads core java.* classes. Flags affect module path and platform class discovery on modular JDKs.

Class Data Sharing (CDS)

Class Data Sharing writes read-only class metadata to an archive for faster startup and lower RSS when multiple JVMs share the same image (containers, CLI tools).

Class Loader Behavior

Application class loaders delegate parent-first or child-first. Parallel loading speeds startup on multi-core hosts.

Class Unloading

Classes unload when their loader is collectible. OSGi and hot-redeploy need this; leaks keep metaspace pinned.

Loading & Unloading Diagnostics

Trace class loading and unloading to stdout or unified log—useful for NoClassDefFoundError and classpath debugging.

Server-Class Machine Policy

Server-class machine detection picks ergonomic defaults (heap, GC, JIT) when hardware looks like a server (2+ CPUs, sufficient RAM).

Verification & Bytecode

Bytecode verification proves type safety before execution. Split verification and relaxations affect startup in trusted environments.

Concurrency

Java threads map to OS threads (or virtual threads on modern JDKs). Safepoints stop mutator threads so GC and deoptimization can run. Monitor and scheduling flags affect lock contention, time-to-safepoint, and how thread priorities map to the kernel scheduler.

Threads and Synchronization

Safepoints coordinate stop-the-world phases. Monitor flags tune biased locking and inflation. Poor safepoint behavior shows up as long GC pauses or JVM STW metrics in APM tools.

Monitors

Synchronized blocks use monitors. Inflation promotes lightweight locks to heavyweight when contention appears.

Safepoints

Safepoints stop all Java threads at known points for GC roots, deoptimization, and some JVMTI operations. Long "time to safepoint" delays app threads before STW work begins.

Thread Priority

Maps Java thread priorities 1–10 to OS priorities. Rarely fixes performance issues; can starve GC or compiler threads if misused.

Thread Scheduling

Hints to the OS scheduler for JVM-created threads. Effects vary by platform and kernel.

Operations & platform

Production systems need observability: JFR, heap dumps, unified logging, and cgroup-aware defaults in containers. Flags here expose serviceability hooks, security boundaries, and startup properties without changing application code.

Diagnostics

Serviceability: Flight Recorder, heap dumps on OOM, attach API, native memory tracking, and PerfData for jstat. Essential for incident response.

Attach & JMX

Dynamic attach loads agents and connects JMX without restart. Disable in hardened environments to reduce attack surface.

DTrace

DTrace probes on Solaris/macOS for kernel-level correlation with JVM events.

Error Handling

Assert and error reporting behavior in diagnostic builds and when recovering from recoverable VM errors.

Flight Recorder

Java Flight Recorder records low-overhead events (CPU, allocation, locks, I/O) into buffer files for JDK Mission Control and async-profiler correlation.

Flight Recorder

Additional JFR tuning overlapping flight recorder: stack depth, sample periods, and repository paths.

General Diagnostics

Broad diagnostics: version info, flag dumps, and VM state useful in support tickets.

Heap Dumps

Heap dumps capture object graphs for Eclipse MAT, VisualVM, or jcmd analysis. On-OOM dumps are critical for production memory leaks.

Native Memory

Native Memory Tracking (NMT) accounts malloc outside the heap—metaspace, code cache, thread stacks, direct buffers, GC internal structures.

PerfData

PerfData exposes counters to jstat and monitoring tools (heap usage, GC counts).

Tracing & Diagnostics

Unified tracing framework hooks beyond GC logging—JFR events, DTrace probes, diagnostic commands.

Logging

Unified JVM logging (-Xlog) replaced many legacy -XX:+Print* switches. Async logging reduces overhead when diagnostic volume is high.

Async Logging

Unified logging (-Xlog) can use async writers so application threads do not block on disk I/O during high log volume.

Containers

In Docker/Kubernetes, cgroups report CPU and memory limits. The JVM reads them to size heap ergonomics and GC parallelism instead of assuming full host RAM.

CPU Limits

In cgroups v1/v2 environments, CPU quota limits how many GC and compiler threads ergonomics should use. Prevents over-threading on small Kubernetes limits.

System Properties

Some behavioral switches are exposed as flags because they must be set before the VM fully starts.

JVM Properties

VM flags mirroring important system properties that must be set at launch (encoding, locale, agent paths).

Security

Legacy security manager and agent constraints. Fewer flags apply on modern JDKs but remain in catalogs for compatibility.

JVM Security

Security manager, policy files, and agent restrictions. Deprecated for removal but cataloged for legacy enterprise deployments.