β From Source to Runtime: How Java Code is Compiled and Executed (JVM Internals for Intermediate Developers)

Table of contents
- π Java Program Lifecycle: From Code to Output
- π§ What Is the JVM?
- π§° JDK, JRE, and JVM: How They Work Together
- π JVM Architecture Overview
- π§ JVM Memory Breakdown
- π Deep Dive into static: JVM, Misconceptions & Rules
- π The Object Class β Root of All Java Objects
- π How Does Input Reach main() from the Command Line?
- β Recap Table
- π§βπ» Final Thoughts
If you're writing Java code regularly β whether it's for backend services, web applications, or system tools β understanding how your code gets executed isn't just βnice to know.β It's essential.
This blog will walk you through:
How Java code flows from
.java
to executionWhat the JVM really does behind the scenes
Key memory areas: Stack, Heap, and Method Area
How
static
members are stored and usedWhy Java is platform-independent
How input flows into your main method
Clarifying misconceptions around
static
, heap, and object-orientation
Letβs dive deep.
π Java Program Lifecycle: From Code to Output
Letβs consider a simple example:
public class Demo {
public static void main(String[] args) {
int a = 10, b = 20;
int sum = a + b;
System.out.println("Sum = " + sum);
}
}
When you compile and run this code:
javac Demo.java
java Demo
Hereβs what happens:
[.java file]
β Compilation (javac)
[.class file β Bytecode]
β Execution (java)
[JVM loads β verifies β allocates memory β executes]
β
[Output: Sum = 30]
π§ What Is the JVM?
The Java Virtual Machine (JVM) is a software-based engine responsible for:
Loading and executing your bytecode
Managing memory (stack, heap, method area)
Performing garbage collection
Converting bytecode into native code
Hereβs something important:
JVM doesnβt interact with hardware initially. It compiles, validates, and stores the state of your program first β like static methods, static variables, class structure β and only when itβs time to run, it interacts with the actual machine.
The JVM is always in control of:
The state of your program
Its own stack for bytecode execution
Static content loaded directly into the method area
This ability to store program state is what gives the JVM flexibility, efficiency, and portability.
π§° JDK, JRE, and JVM: How They Work Together
Component | Description |
JDK | Full development toolkit (compiler, tools, JRE) |
JRE | JVM + libraries (used for running code) |
JVM | Executes your bytecode (heart of the platform) |
π JVM Architecture Overview
Hereβs what the JVM consists of:
ββββββββββββββββββββββββββββββ
β Class Loader β
ββββββββββββββββββββββββββββββ€
β Runtime Memory Areas β
β (Heap, Stack, Method Area)β
ββββββββββββββββββββββββββββββ€
β Execution Engine β
ββββββββββββββββββββββββββββββ€
β Native Method Interface β
ββββββββββββββββββββββββββββββ
Letβs break these areas down.
π§ JVM Memory Breakdown
1. πΈ Method Area (MetaSpace in Java 8+)
The Method Area is where JVM stores class-level metadata:
Class name, hierarchy
Method bytecode
Static variables
Constant pool (literals, symbols)
When the JVM starts, it directly loads static
members into the Method Area. This happens before any object is created.
Thatβs why:
public static void main(String[] args)
...is accessible without creating an object. It's preloaded!
π‘ This also explains why you get errors like
NoSuchMethodError: main
if yourmain()
is not markedstatic
.
JVM is not concerned about your class object β it just looks for a static main() to begin execution.
π Key Concept:
Whenever memory is allocated to a class, we call it an object. But static members are not part of object memory β theyβre part of class-level memory (Method Area).
2. πΈ Heap
All objects (created via new
) live in the Heap. It is shared across all threads and cleaned automatically using Garbage Collection.
List<String> list = new ArrayList<>();
Here, the ArrayList
object is created in the heap. And remember:
β Thumb Rule: Whenever you use
new
, memory is allocated in the heap.
3. πΈ Stack
Each thread has its own stack memory. It stores:
Method call frames
Local variables
References to heap objects
public class StackDemo {
public static void main(String[] args) {
int num = 10; // Stored in stack
Student s = new Student(); // Object in heap, reference in stack
}
}
π Memory Layout Example
Thread-1 Stack Thread-2 Stack
ββββββββββββββ ββββββββββββββ
β Method A β β Method X β
β Method B β β Method Y β
ββββββββββββββ ββββββββββββββ
Shared Heap
ββββββββββββββββββββββ
β new Student() β
β new Book() β
ββββββββββββββββββββββ
Shared Method Area
ββββββββββββββββββββββββββ
β static int count = 0; β
β bytecode of methods β
β constant pool β
ββββββββββββββββββββββββββ
π Deep Dive into static
: JVM, Misconceptions & Rules
The static
keyword is one of the most misunderstood features in Java. Letβs break it down clearly.
β JVM Behavior:
When JVM loads your class, it immediately loads all static methods and variables into the Method Area.
These are accessible even without creating an object.
β Common Misconception:
"Static methods cannot access the heap."
Not true. Static methods can access heap memory β as long as they reference an object.
But here's the key rule:
β You cannot use non-static members directly inside a static method.
Why?
Because static methods are not tied to any object instance. They belong to the class, not to a particular object. And since instance variables require an object, they can't be used unless you explicitly refer to an object.
Example:
class Example {
int x = 10;
static void printX() {
// System.out.println(x); β Invalid
Example e = new Example();
System.out.println(e.x); β
Valid
}
}
π The Object Class β Root of All Java Objects
In Java, every class implicitly extends java.lang.Object
.
This is why:
Every class has methods like
toString()
,equals()
, andhashCode()
All containers (List, Set, Map) inherit from
Object
JVM treats Object as the ultimate superclass
ArrayList<String> list = new ArrayList<>();
Here, the ArrayList
object is created in heap. But internally, it derives from Object, giving it polymorphic behavior.
β Java is object-oriented β but not 100% β because it supports primitive types (
int
,char
,boolean
, etc.).
These primitives are not objects. Thatβs why Java is said to be "not purely object-oriented."
Still, Java gives you Wrapper Classes (Integer
, Character
, Boolean
) to treat primitives as objects when needed.
π How Does Input Reach main()
from the Command Line?
Whenever you run:
java Demo Hello World
The arguments "Hello"
and "World"
are passed as a string array to your main method.
public static void main(String[] args) {
System.out.println(args[0]); // Hello
System.out.println(args[1]); // World
}
JVM automatically reads input from stdin
, splits it by spaces, and places each token into the args[]
array.
β Recap Table
Memory Area | Stores | Thread Scope |
Method Area | Static data, class structure, bytecode | Shared |
Heap | Objects and instance fields | Shared |
Stack | Local variables, method calls | Per Thread |
π§βπ» Final Thoughts
By now, you should be able to visualize exactly what happens:
When the JVM loads a class
How
static
methods and variables are storedWhere objects go (heap)
Why you canβt access non-static things from static methods
And how everything starts from
Object
Understanding these internals helps you debug more intelligently, write more performant code, and prepare confidently for interviews.
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 π¨βπ»π