Java Virtual Machine (JVM)

What is meant by a Virtual machine?

Virtual — Something that is not real.

Machine — Some item that helps to do your work.

So, a Virtual Machine means a machine that is not real. Virtual Machines can be divided into 2 main types.

  1. System based Virtual Machines ( SVM )

Contains hardware components and creates multiple environments to work. These environments are completely independent of each other.

Examples — Hypervisor, Xen.

2. Application Based Virtual Machines ( AVM )

No hardware components involved. May have software that helps to create a platform to run other programs.

Examples JVM, CLR( Common Language Runtime ), PVM

So this is basically a process. Therefore these VMs are also known as Process-based Virtual Machines.

JVM — Java Virtual Machine is completely a specification.

JVM comes with the Java Runtime Environment( JRE ) which is tightly coupled with the platform. When you download JRE for a particular platform, it will also deploy the code required to create JVM instances for that platform. When we execute a Java Program, a JVM instance is getting created and it will convert the Bytecode into machine code. These JVM instances exist until we run the program.

How JRE knows when to create a JVM instance?

Compiling and Running a simple java program will look like —

‘javac Helloworld.java’

‘java Helloworld’

The moment when we type the java keyword, we basically tell the OS to give a JVM instance.

A JVM instance is a non-daemon thread. JVM will take the “public static void main” method and execute it.

JVM instance may get destroyed when —

  1. If the non-daemon thread exits.
  2. Application call the system exit method.
JDK, JRE, AND JVM

Photo: https://javainterviewgoal.blogspot.com/2019/07/what-is-jdk-jre-and-jvm.html

Main components of the JVM

  1. ClassLoader
  2. Memory Area
  3. Execution Engine
Components of JVM

Photo: https://en.wikipedia.org/wiki/Java_virtual_machine

There are 2 types of class loaders.

  1. Bootstrap class loader.
  2. Custom-defined class loader.

Main responsibilities —

  1. Loading
  2. Linking
  3. Initialization

Loading —

Take the class files and put those into the memory. Apart from this main task, the loading process will do several other sub-tasks.

  1. When JVM is reading the file, it will do the following tasks.
  • Read fully qualified class name.
  • Read variable information.
  • Read immediate parent information.
  • Check whether is a class, interface, or an enum.

2. JVM creates an object of type “Class” for all the successfully loaded classes. Only 1 object is created per class. This object will be stored in the heap.

There are 3 main steps in the linking phase.

  1. Verification

The “byte code verifier” will check the code for —

  • Tampering
  • Validity of the compiler
  • Code structure and format

If an error is detected, JVM will throw a runtime exception called Verifier exception. Else JVM will move to the next stage.

2. Preparation

Default values will be assigned to all the class variables. There is a default value for each data type.

3. Resolution

Resolution is the process of locating classes, interfaces, fields, and methods and replace those symbolic references with direct references. This is done because all the domain-specific names cannot be read by the JVM at the machine level. Therefore the simple links are replaced with direct links.

At this phase, all the real values will be re-assigned. If there is a static block in the class, it will get executed at this stage.

This can be divided into 5 sub-areas.

  • Method Area: Keeps information about the class. Only 1 Method Area per JVM.
  • Heap: Keeps the information about objects. Only 1 per JVM.
  • Stack: Keep the information about the methods. A separate frame is created per method.
  • PC Registers: If the method is a non-native method, PC Registers will hold information about the next execution.
  • Native Method Area: If JVM accesses a native method, information about that method will be stored in this area.

The central component of the JVM and communicates with various memory areas of the JVM. The class files are executed by the execution engine. The execution engine contains 3 main components.

  1. Interpreter: Converts the byte code into machine code and executes them in a sequential manner. However, the problem with this is that it will convert the same method multiple times which causes a reduction in the overall performance.
  2. JIT Compiler: Overcomes the slow execution problem of the interpreter. Compiles bytecode into native machine code at run time.
  3. Garbage Collector: A program in Java that is used to manage the memory automatically. Free up the memory by removing unreachable methods.

I have used the following playlist by Mr. Krishantha Dinesh to gather the required information.

Associate Software Engineer at Virtusa