Java Virtual Machine Architecture (JVM)
Hey, you are……
This is my very first blog in the medium. I’m very excited to share my knowledge with readers.
We all are very known with JVM in java. It’s a Java Virtual Machine used to run the java program. In comprehensive, when the java program runs it’s used to convert the byte code into machine code. But this is not only what JVM does. It’s a very broad area of knowledge.
Before the JVM, let’s understand Java.
If you have no prior knowledge of Java, you won’t face any difficulty. If you are an experienced java developer, this blog will help you brush up on the concepts.
Java is a popular programming language. It’s open-source and free, works on different platforms, having object-oriented language, a wide variety of using many applications like mobile, web, games, desktop, and so on.
What’s JVM??
JVM(Java Virtual Machine) acts as a run-time engine to run Java applications. This is a Virtual Machine. we have to break the two parts of this. One is Virtual other, Machine. The concept of virtual is not real, we can simulate the environment to make feel as real. A machine that we already know it’s a kind of device or item that can help to do the work. So JVM is a machine but not a real (it’s not existing) so we can’t download it on our machine.
Then how can derive JVM?
By considering the figure;
- JVM is the virtual machine that runs the byte code in java.
- JVM can be loaded on various hardware platforms, bytecodes are the machine language of JVM.
- JRE is a java runtime environment that is sufficient to run the program.
- JRE = JVM + library files (java package classes).
- JDK is a java development kit, required to write, compile and run a program.
- JDK = JRE + Tools needed to develop a java program.
When we need to run the java program must install JRE and JDK. JRE is a java RunTime Environment and JDK is Java Development Kit. when installing JRE and JDK, JVM is not installed as we know that it’s not existing. But when install JRE, It will deploy the code which requires to create JVM for the run time environment.
So when executing the java program, JRE creates the JVM instance and it creates JVM, for that JVM help to convert the byte code into machine code in different platforms.
And when we type the command in the terminal/CLI as
“javac HelloWorld(filename).java” — and enter what it does is, it will create the HelloWorld java file.
“java HelloWorld(filename)” — what this java keyword does is, it’s telling our operating system to create a JVM instance for this class file.
JVM instance when it’s created, it creates a nondemand thread. When JVM instance creates what it does is it will take this“public Static void main(String args[ ])” method to execute, from there onwards it can drive this program through this method.
In a computer, executing different programs at the same time, in every each execution JVM will get creates for that program for example if executing five different programs on the computer at the same time, there will have five different JVM are created and work until that each program gets exit.
There are two ways to JVM gets destroyed.
1. If no nondemand threads exist.(That means all the non-demand thread which were created are closed/destroyed. So the JVM instance gets to die.
2.If we use the exit(); method in our system.
There are two types of virtual machines in Java,
1. System based Virtual machine (SVM)
2. Application based / Process Based Virtual Machine( AVM).
System Based Virtual machines are having one or more hardware components that can create multiple environments to work. These environments are not dependent. For example Hypervisor, VirtualBox, Xen
The Application-Based Virtual machines have applications/ software that can help to create a platform to run another program. There are no hardware components involved, only processes. That’s why it’s called Process-based VM. There is a platform that helps to produce the output for a given input. JVM, CLR(computer language runtime), PVM(parrot virtual machine) are some examples of AVM.
Main Components of JVM
1. ClassLoader
2. Memory Area
3. Execution Engine
1. ClassLoader
During the execution, java class files are loaded into the memory area. This functionality is called Java dynamic class loading.
The ClassLoader is classified into three jobs;
- Loading
- Linking
- Initialization
1. Loading
There are three types of class loaders are in;
- Bootstrap ClassLoader
- Extension ClassLoader
- Application ClassLoader
These loaders are helpings to load the class file into the memory area. Before loaded to the memory area, JVM will read the class file’s fully qualified name, instance variable information, and immediate parent information, check whether it is an enum, class, or interface.
For the very first time, each and every class is loaded, JVM will create the object from the data type “Class”. There is only one object created per class ( Example; Human human= new Human(“John”).
2. Linking
Linking occurs in three stages
2.1 Verification
Java has a safe execution environment because the bytecode verifier will exactly check if the byte code will safely execute or not. In this process, a “Byte code verifier” is used to verify whether byte codes are generated by a valid compiler or not, whether the bytecodes are correct structure, and whether this class file has correct formatting or not.
Once the error is detected, Java will throw the runtime exception call Verifier Exception. when the verification is completed, it moved to the preparation
2.2 Preparation
The function that happened in the preparation process is to assign a default value for variables. In the class file if used any instance-level variables or static variables, then assign a default value for that (Not an initial value)
2.3 Resolution
In the Resolution process, all the symbolic references are replaced with direct references(Replacing symbolic link with direct link). Because in Machine level JVM cannot read by Domain-specific names.
3. Initialization
This is the final stage of the ClassLoader, In the initialization process, there is an original value assigned for variables that are in the class file, and a static block will be executed.
The Initalization must be do before each class have an active use .This is a basic rule for find an active use for a class.
- An instance of a class is used to create a new() keyword.
- The class have a particular static method it will invoke
Ex: Employee.verify() - Assigned value for the static field
Ex: Employee.code = “a” - Reflexion API to create an object
- Initial class (main method)
- Instantiation of sub-class.
The initialization process happens in four ways
- Using new keyword
Ex : Employee S= new Employee(); - Clone();
- Reflexion API
Ex: getInstance(); - IO.ObjectInputStream
(If put value, Initial value will assign to non-transient value)
When the initialization process JVM will create an init method for classes. This init method is dependent on the class structure. In java, there are 3 kinds of codes in the init method.
Invoke some other constructor init method
Initialize instance variable
Create bytecode for constructors.
2. Memory Area
Memory Area used to store the class file’s information. It’s split into five major components which are Method Area, Heap Area, Stack, PC Registers, and Native Method Area.
2.1 Method Area
When loading the class file using the class loader it will load class information to the Memory Area. Whether the class file has class level data ( static variable), memory will allocate in the method area to store the static value. The method area is a shared resource which means one method area per JVM. It will share the memory for multiple threads so when data stored is not Thread-safe.
2.2 Heap Area
Information of all the objects and those corresponding arrays, instance variables are stored in Heap memory. When creating an instance, memory will allocate for the object in heap memory. This is a shared resource ( one heap area per JVM). It’s also not Thread-safe.
2.3 Stack
For every thread, every runtime stack will be created (JVM creates one runtime stack for every single thread). When threads start, JVM creates a separate runtime stack and store the method calls. For that every method call, one frame will be created and pushed into the store to the runtime stack.
2.4 PC Registers
Each thread having a single thread. If it’s not a native method these registers will hold the information about the next execution. It usually keeps track of instructions.
2.5 Native Method Area
If JVM accesses the native method, the information about the native method will be stored in this area. For every thread, every native method stack will be created.
3. Execution Engine
The byte code which is assigned to a memory area will be executed by the Execution Engine. This Execution engine will read the code and execute line by line. It will contain three components
- Interpreter
The interpreter is interpreting the bytecode to execute the instructions. The interpreter interprets the byte code faster but it executes slowly. The main drawback of the interpreter is when a method is called multiple times, every time a new interpreter is needed.
2. JIT(Just-In-Time) Compiler
JIT compiler overcomes the issue in the Interpreter. It is more efficient than an Interpreter. This will help to compile the entire byte code and changes it into native code, so when the repeated multiple method calls occur, this native code will be used. Due to that, it will increase the performance of the system.
3. Garbage Collector
The main function is to destroy the unreferenced objects in other words deallocate (freeing) memory for the objects which are no longer needed by running the application.