Skip to main content

Java Virtual Machine

Java Virtual Machine

I will start this blog with the details of Java Virtual Machine. This will help us understand the other important details of Java language in the coming posts.

History:

Java was developed by James Gosling along with his peers at Sun MicroSystems in June 1991. The idea was to develop a language which allows an application programmer to write the code once and run it on different platforms without changing the source code. The problem with C/C++ languages is they follow the write once and compile anywhere philosophy which means you can write your source code once but it can be compiled on different machines. The issue is it can be compiled on the different machine but it cannot run on all the machines because the code is written to a specific operating system in mind. This problem is solved by Java Virtual machine which acts as an operating system to the application program and converts it into Java bytecode. This bytecode can run on any machine with any operating system. JVM has various runtime data areas - pc Register, stack, heap, method area, runtime constant pool and native method stacks. For an application developer, the most important areas are stack and heap. Let's go into the detail of stack and heap in the next section.

JVM Stack:

Each JVM execution creates a thread and each thread has its own stack that stores the local variables and a reference to the objects stored in heap. During runtime, if a thread requires a larger stack than permitted. JVM throws a stack overflow exception.
Whenever a new method is invoked a new stack frame is created inside the stack. This frame is destroyed when the exception of the method is completed. The current method that is being executed is always at the top of the stack.

JVM Heap:

All the JVM threads share the same heap. Heap stores the java objects and arrays. Array and objects in java are passed by reference. So, they need to exist in the memory even after the method that has created these objects/arrays popped out of the stack frame.

Program Counter:

Each thread of execution has its program counter register. It stores the pointer and the return address. When the thread executes a java method, the address of the current instruction is stored in the program counter register. This address is a pointer to the address in the method area.

Let's see how the values are stored in the stack and frame using a hello world example:

public class HelloWorld {
    private static final String HELLO_WORLD = "Hello World!";

    public static void main(String args[]) {
        printHelloWorld();
    }

    private static void printHelloWorld() {
        Date date = new Date();
        System.out.print(HELLO_WORLD + " Today is " +  date);
    }
}

1. JVM thread will start the execution from the public static void main method. Each thread has its own stack frame that stores the local variables and a reference to the objects in the heap. In this case, the main method will be pushed to the stack.
2. The program counter(PC) of the thread stores the address of the next instruction. In this case, the PC will store the address of the next instruction which is the printHelloWorld method. The printHelloWorld method will be pushed to the stack.
3. Once the printHelloWorld method is pushed to the stack, the JVM thread will start executing the method. The PC will store the address of the instruction Date date = new Date();
4. new Date() will create an object in the heap and a reference to the newly created object is stored in the stack. The PC will store the address of the next instruction that is a print statement to print the date. Once the date is printed the method is popped out of the stack and thread will start executing the main method.
5. In this case, there are no instructions left to execute in the main method, so main method will also get popped out of the stack and the thread execution will be completed.





Comments

Popular posts from this blog

Design Pattern in Java

Why Design Pattern In 1994, four authors Erich Gamma, Richard Helm, Ralph Johnson und John Vlissides published a book titled Design Patterns - Elements of Reusable Object-Oriented Software which initiated the concept of Design Pattern in Software development. The idea was to compile a list of common design patterns which can be used by programmers while designing the complex software. All the design patterns in this book are based on the two principles: • Program to an interface, not an implementation. • Favor object composition over inheritance. Let's discuss these two principles in detail. Program to an interface, not an implementation: This principle means that when we create an object, we should create an object for the interface and not the implementation. Example: ArrayList myList = new ArrayList(); //Bad List myList = new ArrayList(); //Good List myList = new TreeList(); // Good In this example...

Types of Design Patterns

Types of Design Patterns Creational Pattern: This design pattern covers the different ways to create an object. We will discuss all of them in the later posts of this blog: Builder Abstract Factory Factory Method Object Pool Prototype Singleton Structural Pattern: Once an object is created, the next job is to create a relationship between the different objects and it can be done using a structural design pattern. The different types of structural design patterns that we will discuss in the future posts are: Adapter Aggregate Bridge Composite Decorator Extensibility Facade FlyWeight Marker Pipes and Filter Opaque Pointer Proxy Behavioral Pattern: In the last two patterns, we have created an object and established a relationship between different objects. Now, we need to figure out ways to communicate with the different objects. Behavioral design pattern helps us in channelizing the communication between the newly created objects. The different ...