Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The JVM runs Java bytecode; just-in-time (JIT) compilation is one way a JVM implementation can speed up frequently executed code. In HotSpot, execution can move from interpretation to compiled code as runtime profiling identifies hot methods. That makes performance change over a program’s lifetime: startup, warm-up, and steady-state speed are different things to measure.

What the JVM does—and where the JIT fits

The Java Virtual Machine (JVM) loads and executes Java bytecode. In HotSpot, that execution involves an interpreter and JIT compilers. The interpreter can start running code without first compiling every method into native machine code. As the program runs, HotSpot gathers runtime information; methods that are executed often enough can be compiled into native code.

This adaptive approach spends compilation effort on code that is likely to matter, rather than compiling every rarely used path up front. The trade-off is that compilation itself consumes CPU and memory, and compiled code occupies the code cache.

How HotSpot’s interpreter, C1, and C2 differ

Execution stage Role Typical trade-off
Interpreter Executes bytecode and gathers runtime profile information. Can begin execution without waiting for compilation, but does not provide the same optimized native code as a top-tier JIT compiler.
C1, the client compiler Compiles code relatively quickly and can produce code that continues profiling. Useful for startup and earlier compiled execution; it generally spends less time optimizing than C2.
C2, the server compiler Uses runtime information to optimize hot methods more deeply. Generally takes more compilation time and memory, but can produce more optimized code for long-running, steady-state workloads.

These are not simply interchangeable compiler choices: they occupy different points in the trade-off between how quickly code is compiled and how much optimization effort is applied. Oracle describes HotSpot as including an interpreter and the C1 and C2 compilers.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How tiered compilation changes performance over time

With tiered compilation, HotSpot coordinates the execution stages. The interpreter collects profile data; C1 can compile code quickly while continuing to profile it; and C2 can later use that longer-running profile to optimize hot methods. Oracle says tiered compilation, introduced in Java SE 7, “brings client VM startup speeds to the server VM.” In the cited Oracle Java 17 HotSpot guide, tiered compilation is enabled by default for the server VM.

The result is adaptive rather than immediate peak performance. A short-lived command may finish before its important methods reach a top compilation tier. A long-running service has more opportunity to warm up and run frequently used code as highly optimized C2 code. Neither behavior means the JVM is simply “slow” or “fast” in every phase.

Tiered compilation also has resource costs. Oracle’s HotSpot performance documentation describes a code-cache requirement that can be up to five times larger for the additional profiling code used by tiered compilation. That is a documented multiplier for that compilation configuration, not a universal code-cache sizing rule for every JDK or application.

Why startup speed and steady-state speed are different

Startup latency includes the time before the application is ready to serve its intended work. Warm-up is the period during which execution, profiling, and compilation are changing the code paths’ performance. Steady-state performance describes behavior after the relevant workload has run long enough for its important paths to settle into their ongoing execution pattern.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Those phases can produce different results because JIT compilation costs CPU and memory, and a short-lived application may not reach its first top-tier compilation. A benchmark that times only a first invocation can therefore measure startup and compilation costs rather than the steady-state speed of the application’s hot code. Oracle’s Graal documentation specifically cautions that short-lived programs may not reach first top-tier compilation and recommends checking which compiler is active and using a representative JMH benchmark.

How to benchmark JVM performance usefully

  1. Decide which phase matters. For a command-line tool, measure startup and the amount of work completed during its short lifetime. For a long-running service, measure warm-up separately from steady-state behavior. Do not treat one number as an answer to both questions.
  2. Use representative code and workload. Benchmark the operations and data patterns that matter to the application. For Java microbenchmarks, use JMH rather than relying on a one-off timer around a method call.
  3. Check what compiler is actually active. This is especially important when evaluating Graal or another compiler configuration: confirm that the intended compiler is supported and active, and that the measured workload reaches the compilation tier being evaluated.
  4. Measure more than throughput. Compare startup latency, warm-up duration, steady-state throughput, response-time and tail-latency behavior, compilation CPU, compiler memory, code-cache occupancy, and repeatability under the same representative workload.
  5. Look for non-JIT bottlenecks. Corroborate benchmark results with profiling and, where appropriate, Java Flight Recorder and JDK Mission Control. Check garbage collection, allocation rate, I/O, locking, thread scheduling, and database behavior; a compiler change will not necessarily improve a workload limited elsewhere.
  6. Record the runtime context. Note the JDK version and distribution, relevant flags, workload, and whether the result is startup, warm-up, or steady-state. Compiler flags, code-cache sizing, and defaults can differ between JDK versions and distributions.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

What JVM thresholds and flags do—and do not—tell you

An Oracle migration document gives 10,000 interpreted method invocations as an example server threshold for the specific HotSpot/JRockit migration configuration it documents. It should not be read as a universal current threshold: defaults depend on the JDK release and distribution.

Oracle documents Graal as an alternative optimizing JIT and gives -XX:+UnlockExperimentalVMOptions -XX:+UseGraalJIT for its documented HotSpot integration. That example is not a portable instruction for every Java runtime. Verify that the exact JDK distribution supports the integration before using those flags, and confirm the active compiler when measuring results.

Similarly, a code-cache value or compiler setting that makes sense for one workload is not automatically right for another. Tuning should follow a measured bottleneck and a version-specific understanding of the runtime, not a copied flag or an assumed universal default.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A practical way to interpret a performance change

  • If the first run is slow but later runs improve, distinguish one-time startup and compilation costs from ongoing execution before attributing the change to application code.
  • If a short benchmark shows no benefit from an optimizing compiler, check whether it runs long enough to reach the intended compilation tier.
  • If steady-state throughput changes, check response-time behavior and resource costs too; a throughput result alone does not describe tail latency or compilation overhead.
  • If changing a compiler setting has little effect, investigate allocation and garbage collection, I/O, locking, scheduling, and database work before assuming the JIT is the limiting factor.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.