JVM- Architecture [pic credit: google]

JVM Architecture:

Rupam Jha
JavaMadeTranquil
Published in
5 min readOct 3, 2020

--

Hello Comrades,

Today we are looking forward to a brief understanding on how the JVM architecture is made and what are the components it holds within. Here we will be understanding the working or say role of all the components. So, let us begin with it!

The JVM architecture is divided into three major portions:

  • Class Loader sub sytems
  • Runtime Data Area
  • Execution Engine

The Class Loader Subsystem:

The Java Class Loader loads the classes into the JVM. All virtual machines include one Class Loader which is embedded into the virtual machines.This embedded loader is called the primordial class loader. This class by default implements the default implementations of loadClass().

A class is loaded in two scenarios , when a new bytecode is executed and when a bytecodes makes static references to a class[ we shall discuss this in detail in further topics].

Java’s dynamic class loading functionality is handled by this Class Loader Subsystem. It basically loads, links and initializes the class files at runtime.

The Java Class Loader is based on three principles :

  • Delegation principle: This principle forwards a request for the class loading to its parent class loader. It only loads the class if the parent does not find or load a class.
  • Visibility principle: This principle gives visibility only to the child class loader to see all the classes are loaded by a parent class, but not vice a versa.
  • Uniqueness principle: This principle allows any class to be loaded only once. It is briefly achievable by the Delegation principle, it ensures that no class which are loaded by the parent class is reloaded by the child class.

The types of Class Loader : The Class Loaders are of following types based on from which path has the class been loaded.

  • Bootstrap Class Loader: It is the parent of all the Class Loaders. It loads the class files from the Core classes. It is also called as Primordial Class Loader. It loads the class from rt.jar file i.e. jre/lib/rt.jar
  • Extensions Class Loader: It is responsible for loading the classes which are inside the ext folder i.e. jre/lib
  • System/Application Class Loader: It is responsible for loading of classes from application class path.

The working of JVM is as follows, the System Class Loader delegates load request to the Extension Class Loader, which further delegates request to Bootstrap Class Loader. If the class is detected in the Bootstrap Class Loader, class gets loaded else request again gets transferred to Extension Class Loader; and yet if the class is not found we get a run time exception java.lang.ClassNotFoundException.

The Runtime Data Area:

The Runtime Data Area is split into Method Area, Heap Area, Stack Area, PC Registers, Native Method Stacks.

Method Area: All the class level information i.e. immediate parent name, class name, methods and variables are stored in Method Area. It contains elements which are used in class and in initialization of Objects and Interfaces. Per JVM a single Method Area is allocated. It is a shared resource. It is common across all the threads.

Heap Area: Detailed information of all Objects is stored into the Heap Area. Heap Area when accessed by any thread is further divided into Young Generation, Old Generation and PermGen[Permanent Generation]. When an object is created it first visits the Young Generation(Eden space) and when it gets older it further moves into the Old Generation. All the static and instance variables are stored in PermGen[will talk in detail on this in Garbage Collection Topic]. Per JVM a single Heap Area is allocated. It is also a shared resource, common across all threads.

Stack Area: JVM creates one runtime stack for every single thread. Every block present into the stack is called an activation record / stack frame which holds all the method calls into it. All the local variable calls are stored into the corresponding frame. After the thread terminates, its stack will be destroyed by the JVM. It is not a shared resource. It throws stackOverFlow error when the stack gets full.

PC Register: Stores the address of the current on going execution instruction of a thread. Each thread having specific PC Register. It basically keeps a track on instructions.

Native Method Stack: Native methods are those which are written in languages other than Java. Stores the Native method information in to it. Each thread owns its Native method Stack. It is same as the Stack Area , except that it is used for native methods.

The Execution Engine: This executes the .class (bytecode) files line by line.It further is classified into : interpreter, Just In Time compiler and Garbage Collector. Interpreter interprets the bytecode and then executes the code. The problem that arises here is , the number of times the any method is called that number of times, the interpreter will be needed. As mentioned in our previous article, JIT compiler is helpful in increasing the efficiency of the interpreter. It compiles the entire bytecode and changes it to the Native code, so that whenever interpreter sees a repeated method calls, JIT compiler provides the directly available Native code, so that re-interpretation is not required; there by increasing the efficiency. JIT compiler is an algorithm, that helps us in compiling as well as interpreting. It performs better for redundant code, but can have an additional runtime overhead, while converting the bytecode to native code. Profiler which is the part of JIT compiler is responsible to identify the repeated method calls. JIT compilation is applicable only to repeatedly invoked methods and not for every method. The function of a Garbage Collector is to destroy un-referenced Objects i.e. deallocating any memory which is no longer needed by the running applications.[will have a dedicated article for GC]

The Native Method Interface : The Java Native Interface [JNI] is basically helpful in having interactions with the native method libraries, required for execution i.e. it acts as a bridge[Mediator] for method calls and corresponding native libraries.

The Native Method Libraries: It is a collection of Native Libraries[c|c++], required by execution engine.

That is it for today! for any further clarifications or add ons thisc article could have, please reach out to me.

Peace Out!

Rupam Pawan Jha

--

--