JVM Internals

Table of contents
- π What Is the JVM and Why Should You Care?
- π What Happens When You Run a Java Program?
- π§± JVM Architecture at a Glance
- π₯ ClassLoader β The Entry Point
- π§ Runtime Memory Areas β Where Java Lives
- βοΈ Execution Engine β The Code Runner
- π§Ή Garbage Collection β The JVMβs Janitor
- β Recap: JVM Components & Their Roles
- π‘ Why JVM Internals Matter to You
- π Conclusion
π What Is the JVM and Why Should You Care?
The Java Virtual Machine (JVM) is what makes Java "write once, run anywhere." When you compile a .java
file, Java doesnβt produce platform-specific machine code. Instead, it creates bytecode, which is understood by the JVM.
The JVM then interprets or compiles this bytecode into native machine code based on your system β whether it's Windows, macOS, or Linux.
But JVM does much more than just run your code. It:
Loads compiled classes into memory
Allocates memory for variables and objects
Runs your methods
Collects garbage (unused memory)
Supports multithreading and concurrency
π What Happens When You Run a Java Program?
Letβs walk through a simple example:
public class HelloJVM {
public static void main(String[] args) {
System.out.println("Hello, JVM!");
}
}
When you run this code using javac
and java
, hereβs what happens internally:
The
.java
file is compiled into a.class
file containing bytecode.The ClassLoader loads this bytecode into memory.
The Bytecode Verifier checks it for security issues.
The Execution Engine runs it line by line or compiles it just-in-time (JIT).
Memory is allocated for variables and objects in the Stack and Heap.
π§± JVM Architecture at a Glance
To understand how the JVM does all this, letβs look at its main components.
βββββββββββββββββββββββββββββββ
β Class Loader β β Loads bytecode (.class files)
βββββββββββββββββββββββββββββββ€
β Runtime Memory Areas β β Stack, Heap, Method Area, etc.
βββββββββββββββββββββββββββββββ€
β Execution Engine β β Interpreter + JIT Compiler
βββββββββββββββββββββββββββββββ€
β Native Interface (JNI) β β Calls to C/C++ native code
βββββββββββββββββββββββββββββββ
These components work together like a well-oiled machine to keep your program running smoothly.
π₯ ClassLoader β The Entry Point
The ClassLoader is responsible for loading all your .class
files (compiled bytecode) into memory. It works in a hierarchy β starting with the core Java classes and moving outward to user-defined ones.
Bootstrap ClassLoader loads core Java classes (like
java.lang.*
).Extension ClassLoader loads JDK-provided libraries.
Application ClassLoader loads your app's classes from the classpath.
Once classes are loaded, theyβre ready to be executed by the JVM.
π§ Runtime Memory Areas β Where Java Lives
The JVM divides its memory into different regions for different purposes. The two most important areas for developers are the Stack and the Heap.
Letβs take a look at them one by one.
πΉ Stack Memory β Method-Level Storage
Each time you call a method, a new stack frame is created to store its parameters and local variables. When the method finishes, its frame is removed automatically.
This is why the stack is fast and doesnβt require manual cleanup.
public class StackExample {
public static void main(String[] args) {
int a = 5;
int b = 10;
int result = add(a, b);
}
static int add(int x, int y) {
int sum = x + y;
return sum;
}
}
In the above example:
a
,b
, andresult
live in the main() stack framex
,y
, andsum
live in the add() stack frame
When add()
returns, its frame is popped off the stack.
πΉ Heap Memory β Object-Level Storage
The heap is where all Java objects are stored when you use new
. Unlike stack memory, the heap is shared across all threads and is managed by the Garbage Collector.
public class HeapExample {
public static void main(String[] args) {
Student s1 = new Student("Alice");
Student s2 = new Student("Bob");
}
}
class Student {
String name;
Student(String name) {
this.name = name;
}
}
In this code:
s1
ands2
are references stored in the stack.The actual
Student
objects live in the heap.
π Memory Layout Example
To tie everything together, hereβs a visual layout of how memory looks during execution:
Thread-1 Stack Thread-2 Stack
ββββββββββββββ ββββββββββββββ
β Method A β β Method X β
β Method B β β Method Y β
ββββββββββββββ ββββββββββββββ
Shared Heap
ββββββββββββββββββββββ
β new Student() β
β new Book() β
ββββββββββββββββββββββ
Each thread has its own stack (used for method calls), but all objects are stored in a common heap space.
βοΈ Execution Engine β The Code Runner
Once memory is ready, the Execution Engine runs your bytecode.
It uses two main components:
Interpreter: Reads and executes bytecode line-by-line.
JIT Compiler (Just-In-Time): Compiles frequently used (hot) code into native machine code for faster execution.
Initially, the interpreter handles everything, but over time, the JIT takes over for performance.
π§Ή Garbage Collection β The JVMβs Janitor
Objects created in the heap are automatically cleaned up when theyβre no longer referenced. This process is called Garbage Collection (GC).
You donβt need to delete objects manually. JVM handles it smartly behind the scenes.
Person p = new Person(); // allocated in heap
p = null; // becomes eligible for GC
GC works in two main regions:
Young Generation: For new objects (frequent GC)
Old Generation: For long-lived objects (less frequent GC)
β Recap: JVM Components & Their Roles
Component | Responsibility |
ClassLoader | Loads .class files into memory |
Stack Memory | Stores method calls and local variables (per thread) |
Heap Memory | Stores all objects and arrays (shared) |
Execution Engine | Interprets or compiles bytecode |
Garbage Collector | Reclaims memory of unused objects |
π‘ Why JVM Internals Matter to You
Knowing how the JVM works is not just academic. It can help you:
Fix memory-related issues like
StackOverflowError
orOutOfMemoryError
Write more efficient, memory-safe code
Understand how threads behave
Prepare for coding interviews
Use tools like VisualVM or JConsole for performance tuning
π Conclusion
The JVM is more than just a black box β itβs a powerful, layered engine that handles everything from loading your classes to managing memory and cleaning up unused data.
Now that you know:
What happens when Java runs
How memory is managed (Stack vs Heap)
What the Execution Engine and GC do
Youβre better equipped to write better, faster, and smarter Java code.
Subscribe to my newsletter
Read articles from Arsh Ghaiwat directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Arsh Ghaiwat
Arsh Ghaiwat
Associate System Engineer | Currently learning Java & building fun side projects | Blogging my dev journey to revise, reflect, and grow π¨βπ»π