Showing posts with label Java Virtual Machine. Show all posts
Showing posts with label Java Virtual Machine. Show all posts

Saturday, September 5, 2026

Java: JVM Inside — The Story Behind JVM (Part 2)

In the previous post, we discussed some basic concepts about the JVM and its role in the Java platform. If you haven't read it yet, you can read Java: JVM Inside — The Story Behind the JVM before continuing with this post.

In this post, let's look a little deeper into what happens inside the JVM and some of the important runtime areas used while a Java application is running.

From Java Source Code to Bytecode

Java source code is compiled by the Java compiler (javac) into bytecode. The bytecode is stored in .class files.

A Java application may contain many classes, so multiple .class files can be packaged together into a JAR (Java Archive) file for easier distribution.

The Java application launcher, java, can be used to start a Java application. The JVM loads the required classes and executes the bytecode.

A JVM may interpret bytecode and can also use Just-In-Time (JIT) compilation to compile frequently executed code into native machine code at runtime. This allows the JVM to optimize application execution while the program is running.

There are also other approaches, such as Ahead-of-Time (AOT) compilation, which can compile code ahead of execution for particular environments.

JVM Runtime Areas

The JVM specification defines several runtime data areas. Some are created for each thread, while others are shared by threads. Important areas include:

  1. Program Counter (PC) Register

  2. JVM Stack

  3. Heap

  4. Method Area

  5. Runtime Constant Pool

  6. Native Method Stack

The JVM specification defines these runtime areas as part of the JVM architecture.

Bytecode Verification

Before bytecode is executed, the JVM performs verification as part of the class loading and linking process.

Bytecode verification helps ensure that class files satisfy the structural and type-safety requirements expected by the JVM.

For example, verification helps check that:

  1. Instructions are used correctly.

  2. Type information is used consistently.

  3. Branches and control-flow information are valid.

  4. Access-control rules are respected.

The JVM specification describes verification as part of the linking process.

JVM Stack

Each JVM thread has its own JVM stack.

The JVM stack contains frames, and a new frame is created when a method is invoked. A frame contains information such as local variables, an operand stack, and information used for dynamic linking.

For example:

Thread
  |
  +-- JVM Stack
        |
        +-- Frame for main()
        |
        +-- Frame for methodA()
        |
        +-- Frame for methodB()

When a method completes, its frame is removed from the stack.

The JVM specification defines JVM stacks and frames as important parts of the runtime environment.

Heap

The heap is the runtime data area from which memory for objects and arrays is allocated.

For example:

Employee employee = new Employee();

When the new operation creates an Employee object, the object is allocated in the heap.

Java does not require developers to manually free this object using a free() operation as in languages such as C or C++. Instead, Java uses Garbage Collection (GC) to automatically reclaim heap memory that is no longer reachable by the application.

Garbage collection is one of the important features of the Java runtime.

A simple way to visualize this is:

JVM
 |
 +-- Heap
 |     |
 |     +-- Object 1
 |     +-- Object 2
 |     +-- Array
 |
 +-- JVM Stack
       |
       +-- Local variables
       +-- Object references

It is common to explain that an object reference can be held in a stack frame while the actual object is located in the heap. However, the exact implementation details of references and memory placement are JVM-implementation dependent, so this should be treated as a conceptual model rather than a strict physical-memory rule.

Arrays in Java are objects, so they are also managed as heap objects.

Method Area

The Method Area is a JVM runtime data area that is shared among threads.

It stores per-class structures such as the runtime representation of classes, methods, fields, and other class-related information.

The method area is not simply a place where "all bytecode is stored." Class files are loaded and linked by the JVM, and the JVM maintains the runtime representation required for execution.

The JVM specification defines the Method Area conceptually, while the exact implementation is JVM-specific.

Runtime Constant Pool

Each class or interface has a runtime constant pool associated with it.

It contains information derived from the constant pool in the class file, including constants and symbolic references used by the class.

The runtime constant pool is important for operations such as dynamic linking.

Final Thoughts

The JVM is much more than a simple program that executes .class files.

It provides a complete runtime environment for loading classes, verifying bytecode, managing memory, executing methods, handling threads, performing garbage collection, and optimizing frequently executed code.

Understanding these JVM runtime areas helps Java developers understand what happens behind the scenes when a Java application runs.

Java: JVM Inside — The Story Behind the JVM

The JVM (Java Virtual Machine) is a core component of the Java platform. JVM stands for Java Virtual Machine.

The JVM is software that provides an execution environment for running Java bytecode. It acts as an abstraction layer between Java bytecode and the underlying operating system and hardware.

Java source code is first compiled into bytecode, which is stored in .class files. The JVM then loads and executes this bytecode.

A simple way to understand the process is:

Java Source Code → Java Compiler (javac) → Bytecode → JVM → Operating System / Hardware

The important point is that the same Java bytecode can generally run on different operating systems as long as a compatible JVM implementation is available.

This is one of the key ideas behind Java's well-known WORA (Write Once, Run Anywhere) concept.

For example, the same .class file can be executed using a compatible JVM on different platforms:

                 Java Source File (.java)
                           |
                           |
                     Java Compiler
                       (javac)
                           |
                           |
                    Bytecode (.class)
                           |
              +------------+------------+
              |            |            |
             JVM          JVM          JVM
              |            |            |
           Windows        Linux        macOS

The JVM specification defines how Java class files and bytecode are handled, while JVM implementations provide the actual runtime environment for a particular platform.

Why is JVM important?

The JVM provides several important capabilities, including:

  • Loading and executing Java class files

  • Managing memory and runtime data areas

  • Garbage collection

  • Bytecode verification

  • Exception handling

  • Supporting Java's platform-independent execution model

  • Providing runtime services needed by Java applications

The JVM specification defines areas such as the heap, JVM stacks, method area, runtime constant pool, and native method stacks.

Therefore, the JVM is one of the fundamental components that makes the Java platform portable across different operating systems and hardware environments.