Understanding JVM Architecture: How Java Runs Under the Hood

Java may be known for its “Write Once, Run Anywhere” mantra, but what makes it possible is the mighty Java Virtual Machine (JVM). Let’s explore its architecture, components, and the runtime journey of a Java application.


The Lifecycle of a Java Program

  • When a Java application starts, the JVM boots up and creates a single thread — the main thread.
  • This thread invokes the main(String[] args) method in the launcher class.
  • The main() method continues to run until the program exits normally or is explicitly terminated.

Event Loop in Action

  • An infinite event loop runs inside main() — constantly polling the event queue.
  • If a task (i.e., a Runnable object) is present in the queue, it gets executed.
  • If the queue is empty, the loop continues to check until the program ends.

🛑 JVM can be explicitly shut down using System.exit() or Runtime.exit().


One JVM = One Application


Key JVM Classes and Interfaces

System.class

  • Manages standard I/O streams:
  • System.in: Standard Input (e.g., Keyboard)
  • System.out: Standard Output (e.g., Console)
  • System.err: Standard Error
  • Provides loadLibrary() method to load native libraries (e.g., written in C/C++).

Runtime.class

  • Acts as the interface between the Java app and the underlying OS environment.
  • Provides hooks to interact with system resources, memory, and process control.

Threads and Runnables

  • Java’s Thread class implements the Runnable interface.
  • A Thread object can be initialized with a Runnable instance:
    “`java
    Runnable task = new MyTask();
    Thread thread = new Thread(task);

JVM and Native Code

  • JVM itself is a native application, typically written in C/C++.
  • Java applications are compiled into bytecode, a platform-independent intermediate code.

JRE vs JDK vs JVM

ComponentDescription
JVMExecutes Java bytecode
JRE (Java Runtime Environment)JVM + Java Class Libraries + Native Libraries
JDK (Java Development Kit)JRE + Development Tools (javac, jar, etc.)

Compilers: JIT vs AOT

Just-In-Time (JIT) Compiler

  • Converts bytecode to native code at runtime.
  • Native code is then executed by the CPU for improved performance.

Ahead-Of-Time (AOT) Compiler

  • Compiles Java code directly into native binaries before runtime.
  • Modern Java apps often use AOT to improve performance and reduce JVM dependency.

AOT enables Java apps to run like native apps without needing a JVM on the target machine.


Summary

The JVM is more than a runtime — it’s the brain behind Java’s portability. From bytecode interpretation to native execution, understanding how it works can help developers write more optimized, efficient, and scalable applications.

Leave a Comment

Your email address will not be published. Required fields are marked *