What is JVM & JIT

In this tutorial, we will learn about two core components of the Java environment (Java Virtual Machine and the Just In Time compiler). We will learn about their internal structure and how they work to execute a Java program.

Java Virtual Machine (JVM)

JVM is virtually a machine on which the Java programs actually run on. A Java program cannot run on a machine without JVM. It is a core part of the Java Runtime Environment (JRE). The JVM is loaded with many specifications that altogether work to successfully run a Java program. It is platform-dependent by nature i.e for each type of operating system there is a different JVM.

A developer need not worry about installing and configuring JVM. It comes built-in with the JDK package.

The platform-independent feature of Java is made possible by JVM. The JVM is the one that can convert the Java bytecode into a machine-understandable code. The conversion of Java Bytecode to machine code takes place in multiple specifications inside a JVM.

Java Virtual Machine

Specifications of JVM

ClassLoader

The ClassLoader is a subpart of JVM. It mainly reads the .class file that is generated using the javac command, extracts some core information from that file, and stores that information in the Method Area. The ClassLoader can get information like classes and their names, variables, methods, interfaces, etc.

Method Area

A method area is like a store where all the class level information like class names, variable names, method names, enums, etc. are stored. It is a unique area in JVM which is shared among other classes.

Heap

We know Java is an object-oriented programming language where everything is in the form of objects. These objects are real entities that need memory to work. The Heap in JVM stores all the data & information about objects that are created during the lifetime of execution of a Java program. Just like Method area, there is only one Heap Area which is a shared resource in JVM.

PC Registers

Program Counter Registers (PC Registers) address storing registers in JVM. These registers store the address of the current instruction that is being executed. Java is a multi-threaded programming language which means there can be multiple threads running at the same time. Java provides multiple PC Registers to store the address of each thread that is being executed.

Execution Engine

The Execution Engine is the one that actually executes the Java bytecode (.class files) inside JVM. The execution engine reads the contents of the .class files line by line and extracts information that is then converted to machine code (which is understandable by the computer). The Execution Engine contains three subparts that collaboratively complete program execution.

  1. Interpreter: The Interpreter is the one which reads the bytecode sequentially one line at a time.
  2. Just In Time (JIT) Compiler: The JIT compiler is mainly used to improve the overall efficiency of the program execution. It converts a similar kind of bytecode to machine code at a time. Whenever the interpreter gets another repeated bytecode, the JIT compiler provides the compiled machine code at that instance of time.
  3. Garbage Collector: Each object created by Java during program execution consumes memory. These objects are later not referenced by the program and therefore are of no use. These unreferenced objects are removed from the memory by the Garbage Collector to manage memory. This increases memory efficiency.

Native Method Stack

A Native Method Stack is used to store information about the native methods that are used in a Java application. There is just one Native Method Stack for one execution thread. Multiple Native Method Stacks are used for multiple execution threads.

Native Method Interface

It is an interface between the JVM and other native libraries like C/C++. Whenever there is a need for external native libraries in JVM this interface is used. This interface can call native libraries or be called by native libraries.

Just In Time Compiler (JIT)

Java programs are really fast in execution. This speed is achieved by the superior performance of Java Virtual Machine. The architecture of JVM has many sub-components that contribute to its performance. The main component on which its execution heavily relies is the Just In Time Compiler (JIT).

The JIT compiler interacts with the JVM at runtime and compiles similar bytecodes into native machine code. This machine code is easily understood by the host machine and can be executed really fast. Whenever there is a repetition of the same code that is being executed, the JIT compiler provides its native machine code at that instance so that the repeated code doesn’t take the same amount of process time again. This saves execution time and increases efficiency.

The JIT compiler achieves much higher execution efficiency only when there is the repetition of the same bytecode. JIT compiles similar bytecodes together and converts them to native machine code. JIT will not be much performance efficient when the repeated code is not frequent.

Oracle uses the Hotspot Compiler to increase the efficiency of program execution. Hotspot compiler identifies and prioritizes Java code so that code with higher priority gets compiled before low priority code.