Chapter[8]: How Does the JVM Run a Java Program? A Beginner-Friendly Guide Using a Car Object
You might have wondered: How does my program run? How does the JVM handle my code, create objects, and manage memory? Don’t worry! Let’s break it all down using a simple Car class example(as we use to do).
The Car Program
We’ll be working with the following program. It introduces the concepts of classes, objects, methods, static and non-static members, and how Java handles memory.
public class Car { // A Car class is created like this
public String color; // anyone can see the car's color
private int mileage; // only the car owner knows its mileage
public static int carCount = 0; // shared by all cars
public Car(String color, int mileage) { // A Constructor, help create an object with proper parameters
this.color = color; // public in nature
this.mileage = mileage; // private in nature
carCount++; // count each new car (static in nature)
}
// Public method to start the engine
public void startEngine() {
System.out.println("Engine started.");
}
// Private method for an internal fuel check
private void checkFuel() {
System.out.println("Fuel level is sufficient.");
}
// Public method to get the mileage
public int getMileage() {
return mileage; // allows limited access to private mileage
}
public static void main(String[] args) { //JVM runs the code from here
Car myCar = new Car("Red", 15000); // create a new car
myCar.startEngine(); // start the engine
System.out.println("Car color: " + myCar.color); // access public attribute
System.out.println("Car mileage: " + myCar.getMileage()); // get mileage through a public method
System.out.println("Total cars: " + Car.carCount); // access static variable
}
}
Step-by-Step: How the JVM Executes the Program
Let’s break down what happens when the JVM runs the program.
1. Finding the Entry Point
The JVM always looks for the main
method as the program's starting point. This method must be static, meaning it can be called without creating an object of the class.
Why static?
If main
weren’t static, the JVM would need an object to call it, and to create an object, it would need another method to execute first. This would create a chicken-and-egg problem! By making main
static, the JVM can directly access and execute it.
2. Loading the Class
Before executing the main
method, the JVM loads the Car
class into memory:
- The Static Area stores the
carCount
variable since it’s marked asstatic
. - The Methods Area prepares the code for all methods (
startEngine
,getMileage
, etc.) so they can be executed when called.
At this point, no objects are created yet. Only the class blueprint is loaded.
3. Executing the main
Method
Once the main
method is loaded, the JVM starts executing its code line by line:
a. Creating an Object
The line:
Car myCar = new Car("Red", 15000);
new
Keyword: This tells the JVM to create an object of theCar
class.- Constructor Call: The
Car
constructor is executed to initialize the object: color
is set to"Red"
.mileage
is set to15000
.carCount
is incremented to1
.
The object is stored in the Heap memory, and the reference variable myCar
is stored in the Stack memory.
Diagram of the Reference
Stack Memory Heap Memory Class Area
+----------+ +-------------------+ +-----------------+
| myCar | --------> | Object: myCar | | Static: carCount|
| (ref) | |-------------------| | Value: 1 |
+----------+ | color: "red" | +-----------------+
| mileage: 5000 |
+-------------------+
b. Starting the Engine
The line:
myCar.startEngine();
- The JVM finds the
startEngine
method in the Methods Area and executes it. - It prints:
“Engine started.”
c. Accessing Public Variables
The line:
System.out.println("Car color: " + myCar.color);
- Since
color
is public, the JVM directly accesses it from the object in the Heap. - It prints:
“Car color: Red”
d. Getting Private Variables
The line:
System.out.println("Car mileage: " + myCar.getMileage());
- The
mileage
variable is private, so it cannot be accessed directly. - Instead, the JVM calls the public
getMileage
method, which returns the value ofmileage
. - It prints:
“Car mileage: 15000”
e. Accessing Static Variables
The line:
System.out.println("Total cars: " + Car.carCount);
- The
carCount
variable is static, meaning it belongs to the class and not any specific object. - The JVM accesses it directly using the class name (
Car.carCount
) and prints:
"Total cars: 1"
Memory Management: Where Does Everything Go?
Here’s how the JVM organizes memory for this program:
Memory Areas:
1: Static Area:
- Stores the
carCount
variable, shared by all objects. - Exists as long as the class is loaded.
2: Heap Memory:
- Stores the
Car
object (myCar
) and its instance variables (color
andmileage
). - Each object gets its own space in the Heap.
3: Stack Memory:
- Stores reference variables (
myCar
) pointing to objects in the Heap. - Also holds local variables during method execution.
Line Diagram for Visualization
Here’s a simplified representation of the memory layout after creating one Car
object:
+----------------+
| Car Class |
+----------------+
| Static: |
| carCount = 1 | <-- Shared by all objects
+----------------+
| Constructor |
| Methods: |
| - startEngine()|
| - getMileage() |
+----------------+
Instance: "myCar"
--------------------------------------------
| | |
+-------------+ +--------------+ +-------------+
| myCar | | myCar | | Static Area |
+-------------+ +--------------+ +-------------+
| color: Red | |mileage: 15000| | carCount: 1 |
+-------------+ +--------------+ +-------------+
Static vs Non-Static (Instance)
Static Variables and Methods
1: Belong to the Class:
- Static variables and methods are associated with the class itself, not individual objects of the class. They are shared among all instances of the class.
2: Accessed Through the Class Name:
- Static variables and methods should be accessed using the class name (e.g.,
Car.carCount
). - While it is technically possible to access them using an object reference (e.g.,
myCar.carCount
), this is not recommended because it can be misleading. It suggests that the variable or method belongs to the object, which is incorrect.
3: Example:
- A static variable like
carCount
might be used to track the total number ofCar
objects created, irrespective of the specific instance.
Instance Variables and Methods
- Belong to individual objects.
- Each object has its own copy.
- Example:
color
andmileage
are specific to eachCar
object.
Why is main
Static?
The main
method is static so that the JVM can execute it without needing an object. The program starts here, and objects are created only when explicitly instructed (e.g., using new Car(...)
).
Summary of Key Concepts
- JVM Entry Point: The
main
method must be static so the program can start without creating an object. - Object Creation: Objects are created only when the
new
keyword is used. - Memory Management:
- Static Variables: Stored in the Static Area, shared by all objects.
- Instance Variables: Stored in the Heap, unique to each object.
- Stack Memory: Holds reference variables and local method variables.
- Access Modifiers:
- Public: Can be accessed from anywhere.
- Private: Only accessible within the class.
- Static vs Instance:
- Use static for shared data or behaviors (e.g.,
carCount
). - Use instance variables for object-specific data (e.g.,
color
).
Memory Diagram Explanation:
1. Class Area:
- Stores static variables and methods that are shared among all objects.
Class: Car
+---------------------------+
| static carCount: 1 | (shared by all instances)
+---------------------------+
2. Heap Memory:
- Stores the actual objects and their instance variables.
Heap Memory
+---------------------------+
| Object: myCar |
|---------------------------|
| color: "Red" | (public instance variable)
| mileage: 15000 | (private instance variable, accessed via getMileage())
+---------------------------+
3. Stack Memory:
- Stores references to objects and method call information.
Stack Memory
+---------------------------+
| Method: main() |
|---------------------------|
| myCar -> (points to heap) |
+---------------------------+
With this detailed breakdown, you should now understand how the JVM processes a program like our Car
example, manages memory, and executes your code. The magic of Java lies in its structure and the JVM’s ability to handle all this complexity behind the scenes! 🚗
Happy Coding