Java Virtual Machine – Architecture and Working

In this article, we will be talking about a very important concept in Java called “Java Virtual Machine”. As we proceed through the article, we will be looking at various topics like the architecture of JVM, its working, the languages supported by JVM, and the process of garbage collection, and finish off by looking at the evolution of JVM through the years.

What is Java Virtual Machine?

The Java Virtual Machine (JVM) is a software program that provides a runtime environment for Java applications and code. JVM converts the bytecode of Java programming language into a machine language. Technically speaking, JVM (Java Virtual Machine) is a part of JRE (Java Runtime Environment).

When compared to other programming languages like C, Python, and C++, the compiler produces machine code for a particular system, but in Java, the compiler produces code for a Virtual Machine known as JVM.

What is the role of JVM?

Technically, the JVM has two primary roles. One is to allow Java programs to run on any device or operating system, and the second is to manage and optimize program memory.

To talk more about the different things the JVM does, it Loads code, verifies code, executes code, and provides a runtime environment. Java Virtual Machine also gives definitions for the garbage-collected heap, memory area, class file format, register set, and much more.

What are the languages supported by JVM?

You might think it is stupid to ask this question, as the name itself clearly say “Java”…right? Well, it was once only for Java, but today, JVM is powerful and flexible enough to support many other languages today.

Other than Java, the other popular programming languages supported by JVM are Scala (used for concurrent and real-time applications), Groovy (a dynamically typed scripted programming language), Kotlin (a language that delivers a blend of object-oriented and functional styles), and many more.

The Architecture of Java Virtual Machine:

Before we proceed to a further topic, let us take a moment to discuss the architecture of JVM. Below is the schematic diagram of JVM’s architecture:

what is jvm classloader

Let us take a deeper dive into each of the eight subsystems:

1. Classloader: This subsystem loads class files whenever we run the Java program. In Java programming language, there are three inbuilt classloader; let us take a look at them:

a. Bootstrap classloader: The classloader being discussed is the parent class of the Extension classloader. The bootstrap classloader loads the rt.jar file. This file contains all class files of Java Standard Edition.

These files include java.lang package classes, java.net package classes, java.util package classes, java.io package classes, java.sql package classes, etc.

b. Extension classloader: The extension classloader is the child classloader of Bootstrap and the parent classloader of the System classloader. This classloader loads the jar files located inside the directory “$JAVA_HOME/jre/lib/ext”.

c. System classloader: The system classloader or the application classloader is the child classloader of the Extension classloader. This classloader loads the class files from the classpath. The classpath, by default, is set to the current directory. The classpath can be changed by using the “-cp” or “-classpath” command.

Let us understand the topic of class loader by looking at a program:

public class FirstCode 
{  
    public static void main(String[] args)  
    {  
        Class c=FirstCode.class;  
        System.out.println(c.getClassLoader());  
        System.out.println(String.class.getClassLoader());  
    }  
}    

Output:

jdk.internal.loader.ClassLoaders$AppClassLoader@4b85612c
Null

When we try to print the classloader name of the current class, the system classloader will load this class.

However, if we try to print the classloader name of String, it will print null because it is an in-built class that is found in rt.jar, so it is loaded by the Bootstrap classloader.

1. Class Area: this subsystem stores the structures per class like runtime constant pool, method data, code for methods, and so many more

2. Heap: The heap subsystem is the runtime data area in which objects are allocated.

3. A stack is a data structure that holds local variables and partial results and is used in method invocation and return. Every thread has a dedicated private Java Virtual Machine stack that is created at the same time as the thread.

4. PC register: the PC register or the program counter register holds the address of the JVM that is currently being executed.

5. The native method stack is a stack that stores all of the native methods used in an application.

6. Execution Engine: the execution engine contains three different components: a virtual process, an interpreter that takes the bytecode and translates it into machine code (native code), then executes it one instruction at a time., and the just-in-time compiler. The third component, the JIT compiler, compiles parts of the byte code that have similar functionality. The JIT compiler improves the performance of the system by overcoming the interpreter’s drawback of slow execution. It does this by compiling code into machine code at runtime, which makes it faster to execute.

7. The Java Native Interface (JNI) is an application programming interface (API) that allows Java code to interact with code written in other programming languages. The framework of Java Native Interface sends output to the Console or interacts with OS libraries.

The working of JVM: code compilation and execution process

For you to code in Java, you need a couple of modules; let us take a look at each one of them and what it is used for:

1. Editor: First, you need something to type your program in; that is where the editor comes into the picture. A notepad will also suffice for this purpose.

2. Compiler: Once you are done writing the code, you need a compiler to convert your high-language program into native machine code.

3. Linker: The role of the Linker is to combine different program files that are referenced in your main program together.

4. Loader: The loader loads the files from your secondary storage device into the RAM. This process is automatically done when you execute the code.

5. Execution: The operating system and the processor handle the execution of the code written.

How are the executable files loaded into JVM?

We have taken a brief look at the different modules that are a part of the working of the JVM. Let us go a little deeper to understand the function of JVM. The working of a Java Virtual Machine depends on two modules: A Java class loader and a Java execution engine.

1. Java class loader:

Just like everything in Linux is a file, everything in Java is a class. This means that all Java applications are built from classes. Therefore, to run a Java application, the JVM must load all the “.class” files into a server where they can be accessed.

The class loader uses the techniques of caching and lazy loading to make class loading as efficient as it can be. Let us understand this by looking at a program:

2. Java execution engine:

After the classloader has finished its work, the code begins the execution of each class. This is where the execution engine comes into the picture, as code execution involves managing access to system resources. This module manages resources for file system access and network input/output.

How is JVM responsible for garbage collection?

One of the most crucial features of Java Virtual Machine is to check the memory usage in the heap and stack. Before Java came into the picture, memory management was done by the programmer, but with Java, this is done with the help of JVM.

Garbage collection is done by the JVM through a process called garbage collection. This process involves continuous identification and elimination of unused memory in Java programs.

JVM over the years and beyond

The key feature, like standardized configuration, monitoring, and management, of JVM make it a perfect fit for technologies using containerized development like Docker and Kubernetes.

JVM also works brilliantly as a PaaS (Platform-as-a-service), as it is well suited to microservice architecture. Moreover, in the coming years, Horizon is looking to introduce virtual threads to the JVM to make it capable of concurrency at higher abstraction on top of operating system processes.

Conclusion

As you have seen, Java Virtual Machine is a key concept in Java that helps in creating an environment for the execution of the programs. With the introduction of JVM, it revolutionized many things like garbage collection. In fact, the very reason Java gets its nickname “write once, run anywhere” is because of JVM itself!

Leave a Reply

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