Java code runs on the JVM when a JVM process loads class files, prepares runtime structures, and executes the program’s bytecode or compiled machine code while managing memory, threads, and runtime services.
Learning Question
When I run a Java program, what is actually running?
It is easy to say, “the JVM runs Java.” That phrase is useful in daily work, but it hides several different layers.
The JVM does not execute Java source code directly. Java source code is first compiled into class files. Class files contain bytecode and metadata in a binary format that the JVM can load and inspect. At runtime, the JVM starts inside an operating system process, loads the required classes, creates runtime representations of those classes, and begins executing the application’s entry point.
The first mental model is:
Running Java means running a JVM process that executes class-file behavior while managing runtime state.
The Important Separation
Several concepts are easy to collapse into one word:
| Level | What It Is | What It Is For |
|---|---|---|
| Java source code | Text written by the programmer | Describing program behavior in the Java language |
| Class file | Binary output of compilation | Holding bytecode and metadata in a JVM-loadable format |
| Bytecode | JVM instruction form inside methods | Describing operations for the JVM execution model |
| JVM process | Operating system process running a JVM implementation | Hosting class loading, execution, memory management, and runtime services |
| Java thread | Thread of execution managed through the JVM | Running Java frames and interacting with shared runtime state |
| Machine code | CPU-executable instructions | What the physical CPU ultimately executes |
The CPU does not execute Java source code. It executes machine instructions.
When bytecode is interpreted, the CPU executes the interpreter’s machine code, and that interpreter performs the bytecode operations. When bytecode is JIT-compiled, the JVM produces machine code for hot code paths, and the CPU executes that generated machine code directly.
In both cases, source code is not the thing literally executed by the CPU.
The Simplified Runtime Path
A simplified path looks like this:
Java source code
-> javac compiles source into class files
-> java launcher starts a JVM process
-> JVM loads, links, and initializes classes
-> JVM invokes the application's entry point
-> JVM interprets or compiles bytecode
-> CPU executes machine instructions
-> JVM manages memory, threads, GC, and runtime metadataThis flow is simplified. Later chapters separate class loading, stack frames, heap allocation, garbage collection, JIT compilation, safepoints, and diagnostics more carefully.
For now, the important point is that “Java runs” means a runtime system is actively maintaining execution state. The JVM is not only a file format reader and not only an abstract machine. It is a running process with memory, threads, native code, generated code, class metadata, and coordination mechanisms.
What the JVM Provides
The JVM gives Java programs a managed runtime environment.
The most important runtime services are:
- loading class definitions when they are needed
- verifying and linking class files
- creating and managing stack frames for method calls
- allocating objects on the heap
- tracking references and reclaiming unreachable objects
- coordinating Java threads and synchronization
- interpreting bytecode or compiling hot code into machine code
- preserving enough runtime information to produce stack traces, thread dumps, GC logs, and other diagnostics
These services are why Java execution feels different from directly running a native executable. The Java program runs inside a runtime that actively participates in execution.
Why This Distinction Matters
Many practical JVM problems are confusing because the wrong level is being used.
If a program fails with ClassNotFoundException, the problem is not that Java syntax is wrong. It is that the running JVM could not locate a class definition at runtime.
If a program throws OutOfMemoryError: Java heap space, the problem is not that a local variable is too large by itself. It is that heap allocation could not be satisfied after the JVM tried to manage heap memory.
If the first request after deployment is slower than later requests, the reason may involve class loading, initialization, cache warmup, or JIT compilation. It is not enough to say “the code is slow.”
If a thread dump shows many blocked threads, the problem is about runtime thread state and synchronization, not about lines of source code existing in isolation.
The useful diagnostic question is:
At this moment, am I talking about source code, class files, bytecode, a JVM runtime structure, generated machine code, or operating system behavior?
What This Chapter Does Not Explain Yet
This chapter only defines the basic meaning of Java execution on the JVM.
It does not yet explain the class file format, class loading, runtime data areas, stack frames, object layout, garbage collection, JIT compilation, or diagnostic tools.
Those topics need the first separation to be clear:
Java source is compiled into class files, and a JVM process turns those class files into managed runtime behavior.
Core Mental Model
Keep these boundaries separate:
- Java source code is the programmer-facing representation.
- Class files are the JVM-loadable representation.
- Bytecode is the JVM-level instruction representation.
- A JVM process is the running runtime environment.
- Java threads execute methods through stack frames and shared runtime state.
- The physical CPU ultimately executes machine code, whether that machine code belongs to the interpreter, the JVM runtime, or JIT-compiled application code.
Final Summary
Java code runs on the JVM when class-file behavior is loaded and executed inside a JVM process.
The JVM is the runtime boundary between Java’s portable class-file model and the machine-level execution, memory management, threads, optimization, and diagnostics that make the program actually run.