Java Virtual Machine (JVM)

  • JVM is a virtual machine that enabled your computer to run java program. It is a runtime environment which allows your computer to execute java bytecode.
  • JVM’s implementation is called JRE and it is available for many hardware and software platforms.
  • When ever you run a java command on a command prompt a instance of JVM is created which allows your command/code to be executed in it.
  • JVM resides in the RAM

JVM Perform following operations :

  • loads the code
  • verifies the code
  • executed the code
  • provides the runtime environment.

JVM Architecture

JVM Architecture
JVM Architecture Diagram

A. Class Loader Subsystem

i. Classloader

  • Classloader is a part of JVM which is used to load class files into RAM
  • When ever we run java program it is first loaded by the JVM
  • Build in Classloaders of JVM are :
  • Bootstrap ClassLoader
    • First Class loader
    • Super Class of Extension ClassLoader.
    • It loads rt.jar file which contains all the JavaSE class
      • java.lang, java.net, java.util, java.io, java.sql classes etc.
  • Extension ClassLoader
    • Child Class loader of Bootstrap ClassLoader & Parent of Application ClassLoader
    • It loades the jar files located inside $JAVA_HOME/jre/lib/ext directory.
  • System/Application Classloader
    • This is the child classloader of Extension classloader. 
    • It loads the classfiles from classpath. By default, classpath is set to current directory. You can change the classpath using “-cp” or “-classpath” switch. It is also known as Application classloader.

Printing The Class Loader

package com.classloader.demo;

public class ClassLoaderExample {
	public static void main(String[] args) {
		// Let's print the classloader name of current class.
		// Application/System classloader will load this class
		Class c = ClassLoaderExample.class;
		System.out.println("Current Class is loaded by : "+c.getClassLoader());
		System.out.println("Parent Class Loader of Current Class : "+c.getClassLoader().getParent());
		// If we print the classloader name of String, it will print null because it is
		// in-built class which is found in rt.jar, so it is loaded by Bootstrap classloader
		System.out.println("Built in Class loader : "+String.class.getClassLoader());
	}
}

Loading : It is the process of finding the binary representation of a class or interface type with a particular name and creating a class or interface from that binary representation.

In a nutshell, the loading process basically performs these three functions:

  • Create a binary stream of data from the class file
  • Parse the binary data according to the internal data structure
  • Create an instance of java.lang.Class

Note : Even if a class is malformed (URL of a class is not present) it is noted but not triggered in class loading, it is only thrown when the class’s object or anything related to that class is called.

ii. Linking

It is the process of taking a class or interface and combining it into the run-time state of the JVM so that it can be executed.

  • The linking begins with the process of verification of the class, ensuring that it adheres to the semantics of the language and does not disrupt the integrity of JVM. 
  • ensure that the operation does not crash and the binary data aligns with the format it expects. The loader also checks that a class is a subclass of java.lang.Object with the only exception being the Object class itself. 
  • Verify – Bytecode verifier will verify whether the generated bytecode is proper or not if verification fails we will get the verification or linking error. Tho verification happens at multiple places but officially verification happens at this step
  • Prepare – For all static variables memory will be allocated
  • Resolve – All symbolic memory references are replaced with the original references from Method Area.

Verification

  • The linking begins with the process of verification of the class, ensuring that it adheres to the semantics of the language and does not disrupt the integrity of JVM. 
  • ensure that the operation does not crash and the binary data aligns with the format it expects. The loader also checks that a class is a subclass of java.lang.Object with the only exception being the Object class itself. 

Preparation

  • JVM allocates memory for the class variables and initializes them to default values according to the type of the variable. The actual initialization (with user-defined initialization values), however, does not occur until the next initialization phase.

Resolution

  • JVM locates classes, interfaces, fields, and methods referenced in the constant pool (symbol table) and determines the concrete values from their symbolic reference. 

iii. Initialization

initialization of a class or interface consists of executing its class or interface initialization method.

  • After the class or interface is linked through the process of verification, preparing, and optionally resolving, the initialization phase makes the class ready for its first active use.
  • The process starts with initializing the class variables with the value that the program is expected to start off. 
  •  Therefore, initialization means that the class variables are initialized via some initialization routine described by the programmer and initialize the class’s direct superclass if it has not been already initialized. 
  • The initialization of an interface, however, does not require initialization of its super-interfaces. This is an exception with an interface.
  • Static blocks are executed at this stage
  • All static variables are assigned with the initialisation values

B. Runtime Data Area

Class(Method) Area

  • All class level data is stored here including static variables.
  • There is only method area per JVM and it is shared resources
  • The code for methods.
  • This memory is common and shared across multiple threads.

Heap

  • All the Objects and their corresponding instance variables and arrays will be stored here.
  • There is also one Heap Area per JVM. 
  • This memory is common and shared across multiple threads.(Not Thread safe)
  • For more read Heap in JVM

Stack

  • Java Stack stores frames. 
  • A new frame is created each time a method is invoked.
  • A frame is destroyed when its method invocation completes.
  • It holds local variables and partial results, and plays a part in method invocation and return.
  • Each thread has a private JVM stack, created at the same time as thread.
  • The Stack Frame is divided into three subentities:
    • Local Variable Array – Related to the method how many local variables are involved and the corresponding values will be stored here.
    • Operand stack – If any intermediate operation is required to perform, operand stack acts as runtime workspace to perform the operation.
    • Frame data – All symbols corresponding to the method is stored here. In the case of any exception, the catch block information will be maintained in the frame data.

Program Counter Register

  • Each thread will have separate PC Registers, to hold the address of current executing instruction once the instruction is executed the PC register will be updated with the next instruction.
  • PC (program counter) register contains the address of the Java virtual machine instruction currently being executed.
  • Each thread has its separate PC register.

Native Method Stack

It contains all the native methods used in the application.

C. Execution Engine

Execution Engine contains :

  1. Interpreter
    • Read bytecode stream then execute the instructions.
  2. JIT (Just In time) Compiler
    • It improves performance by compiling similar part of bytecode together and hence reducing the time needed for compilation.
    • The Execution Engine will be using the help of the interpreter in converting byte code, but when it finds repeated code it uses the JIT compiler, which compiles the entire bytecode and changes it to native code.
    • This native code will be used directly for repeated method calls, which improve the performance of the system.
      • Intermediate Code Generator – Produces intermediate code
      • Code Optimizer – Responsible for optimizing the intermediate code generated above
      • Target Code Generator – Responsible for Generating Machine Code or Native Code
      • Profiler – A special component, responsible for finding hotspots, i.e. whether the method is called multiple times or not.
  3. Garbage Collector
    •  Collects and removes unreferenced objects. Garbage Collection can be triggered by calling System.gc(), but the execution is not guaranteed. Garbage collection of the JVM collects the objects that are created.

Java Native Interface(JNI)

  • Java Native Interface (JNI) is a framework which provides an interface to communicate with another application written in another language like C, C++, Assembly etc.
  • Java uses JNI framework to send output to the Console or interact with OS libraries.
  • Basically we load the library file provided by the Native application using System.loadLibrary(“native”);
    and then call the interface provided by them to execute the API of other language

Native Libraries

Native Libraries is a collection of the Native Libraries(C, C++) which are needed by the Execution Engine.

Reference :
dZone
Javapoint
Guru99
JIT Explatation YT
List fo JVM – Active/InActive
Developer.com-ClassLoader

Leave a Comment