Most Java programmers understand and use Java programming language on a daily basis, but only a handful of them know the role of Java Virtual Machine (JVM) in this process.
Have you ever come across a file with a .java or .jar extension? If your answer is no then browse the internet and download a .java/.jar extension file and try running it on your respective systems. The file can run easily, all of this is possible because of JVM.
Java Virtual Machine(JVM)
JVM stands for Java Virtual Machine, it basically creates a run-time environment for the java byte code to get executed or in other words to converts byte code into machine-readable code.
As far as Java is concerned it is a platform-independent language but is only possible because of JVM which is platform dependent i.e it varies from OS to OS.
Now, you may think why is the JVM platform dependent if Java is not? So, the JVM acts as one kind of platform or middleware between the Os and Java language. When we compile the code then the .class file is generated which is based on your kernel version and the kernel depends on your os and so does the JVM.
Structure of the Java Virtual Machine
The simplest definition of the JVM will be it loads the .class file and produce the output. Now to understand JVM is depth, let’s take a look at its architecture.
The java class loader is the one that takes the .class file produced by the compiler as an input and converts it into binary data and saves it in the method area(we will discuss the method area as we proceed further).
It dynamically loads Java classes into the JVM. The run time system of java does not need no to know about these files as it is assigned to the class loader.
When the JVM is started, three class loaders are used:
Bootstrap class loader
The bootstrap class loader is considered the core of the JVM. The bootstrap class loader is generally written in native code (Native code is a computer programming code that is compiled to run with a particular processor and its set of instructions.). rt.jar file is the one that contains all the primary packages and all the primary classes which are required by the JVM.
Extension class loader
Extension class loader is basically a child of the Bootstrap class Loader and as the name suggests it loads extensions of core java classes from their respective JDK Extension library directed by the system property of Java.
System Classloader is responsible for loading all the application level classes into the JVM. It loads the file in the classpath environment variable.
Application classpath is specified to the -cp parameter. This is the parameter in the JVM that specifies the location of classes and packages which are defined by the user. It can be set either via command line or through an environment variable.
It is important to always remember that JVM follows the Delegation Algorithm i.e. it only loads the class if the parent does not found or load the class. So, the System class loader assigns a load request extension class loader which further assigns a load request to the extension ClassLoader which is further transferred to Bootstrap ClassLoader.
If the class is in bootstrap, it will be loaded otherwise it will be passed to the extension classLoader again. After the completion of the process of the loader is unable to locate the class it throws an error stating java.lang.ClassNotFoundException.
JVM has a method that is common across all the threads. The method area is analogous to the storage area for compiled code of a Standard language or similar to the “text” segment in an operating system process.
It stores per-class structures such as the run-time constant pool, field and method data, and the code for methods and constructors, including the special methods used in class and instance initialization and interface initialization.
There is a common exceptional condition associated with the method area i.e. If the memory in the method area cannot be made available to satisfy an allocation request, the Java Virtual Machine throws an OutOfMemoryError.
The PC Register
Here PC stands for program counter. Each JVM thread has its own PC Register, from the name itself you can guess that its basic function is to store the address of the current execution instruction of a thread
The heap is a run-time data area in which memory of all class instances and arrays are allocated.
The size of the heap is generally small which is expanded as required by the computation of the program. The memory of the heap does not need to be adjoining.
Native method Stack
The native method stack is an interface used by any native method. When a thread calls a java method the JVM creates a new frame and pushes it onto the java stack
JVM Stack is a data area created for a single execution thread in the JVM memory. It is used by a thread to store local variables, partial results, and data used by the methods for invocation and returns.
You all remember the .class file generated before by the compiler? This code(byte-code) is read line by line by the Execution Engine and then executed.
It is considered the central component of the JVM. In simple words, it is responsible for maintaining a link between the various aspects such as memory areas.
This execution engine mainly contains the following:
The interpreter is responsible to read the byte code and interpret into machine code or native code and execute that code.
With the aid of an example, let’s understand JIT. Assume that we have a function to print “HackTheDeveloper” in java programming language and assume that we execute or call this function many times in our program, our interpreter can read, interpret and execute every time, assuming that we call the function a thousand times, it will repeat the above procedure for a thousand times, which reduces the efficiency of the program.
In order to overcome this problem, JIT has been implemented which converts the byte code to the native code so that if the same function is called, the JIT will provide the code that will increase the efficiency of the program.