The Java Virtual Machine loads classes, verifies bytecode safety, links symbols, allocates memory, optimizes hot code, schedules execution, and exposes runtime information for debugging and monitoring.
Find classes, verify structure, resolve references, and prepare runtime metadata.
Interpret or compile bytecode into optimized machine-level execution paths.
Manage heap, stacks, object lifetime, references, and garbage collection behavior.
Threads, synchronization, exceptions, JNI/native interop, and observability hooks.
| Stage | What happens | Why it matters |
|---|---|---|
| Class load | Class loaders locate and load binary class definitions. | Defines what code becomes visible at runtime. |
| Verification | Bytecode is checked for structural and safety correctness. | Protects runtime integrity and portability assumptions. |
| Link & initialize | Symbols resolve, static state is prepared, and class initialization occurs. | Builds the executable runtime graph of the application. |
| Execute | The interpreter and JIT cooperate to run hot and cold paths efficiently. | Balances startup behavior with long-running performance. |
| Observe & tune | JFR, jcmd, jstack, and related tools inspect a live process. | Critical for production diagnosis and performance engineering. |
Class loading is where the JVM’s trust model, lazy loading behavior, module visibility, runtime compatibility, and custom isolation strategies all intersect. It deserves its own dedicated page.
The dedicated page covers the built-in delegation hierarchy, N-cardinality custom loaders, class file major version 69 for Java 25, CDS, Loom-era considerations, and loader-related failure modes.
Focus on portability and managed execution.
JIT compilation and performance became central.
Monitoring, profiling, and production tooling matured.
Container awareness, virtual-thread direction, and stronger observability workflows became increasingly important.