In this article, you will learn how a java program compiles and run in simple language. we can write any simple java program in any text editor (Notepad, Sublime Text, Atom, etc) but the condition is your java program should contain correct language syntax and .java formate.
For Example, I have created a simple java program with the name of FirstJavaProgram with.java Formate.
Now after creating this program whenever we compile this program by using java Compile javac it will generate a Bytecode file with the class name and with .class formate. For example below image showing a compilation of the above java program.
After Compilation of the java Program, We can see that bytecode is generated as shown in the below image.
Why Java is Platform Independent?
We can see that after compilation of the java program there is a .class generated automatically. now, this .class file is interpreted by JVM and JVM converts this .class file into machine code(Binary Code). So this is the reason why java is a platform-independent language because it first generates Byte code this Bytecode is further interpreted by JVM which is a machine depended.
Now let's see What is JVM(Java Virtual Machine) but before going to understand we should clear understanding of the whole java program process which is shown in the below Image.
The following figure represents the Java Architecture in which each step is elaborate graphically.
Summary Of Java Architecture
Java Architecture is a collection of components, i.e., JVM, JRE, and JDK. It integrates the process of interpretation and compilation. It defines all the processes involved in creating a Java program. Java Architecture explains each and every step of how a program is compiled and executed.
Java Architecture can be explained by using the following steps:
- There is a process of compilation and interpretation in Java.
- Java compiler converts the Java code into byte code.
- After that, the JVM converts the byte code into machine code.
- The machine code is then executed by the machine.
JVM(Java Virtual Machine)
The main feature of Java is Write Once Run Anywhere. The feature states that we can write our code once and use it anywhere or on any operating system. Our Java program can run any of the platforms only because of the Java Virtual Machine. It is a Java platform component that gives us an environment to execute java programs. JVM’s main task is to convert byte code into machine code.
now lets see every component one by one.
ClassLoader Sub-System
classLoader SubSystem is Responsible for the following three Activities.
1)Loading
2)Linking
2.1 )Verification
2.2)Preparation
2.3)Resolution
3)Initialization
1.Loading
Loading means reading Class files and store corresponding Binary Data in Method Area.
For each Class file, JVM stores the following method in Method Area.
- Fully Qualified Name of the loaded Class or Interface or Enum.
- Fully Qualified Name of its immediate Parent class.
- Variable information
- Method information
- Modifiers information
- Constant Pool Information
After loading .class files into Method Area Immediately JVM will create an object of The type Class to represent Class level binary information on Heap Memory.
For, Example
The Class Object can be used by Programmer to get Class Level Information Like Fully Qualified Name of the Class, Parent Name, Methods and Variables Information Etc.
Note: For Every loaded .class file Only One Class Object will be created, even though we are using Class Multiple Times in Our Application.
2.Linking
Linking Consists of 3 Activities
- Verification
- Preparation
- Resolution
Verification
It is the process of ensuring that the Binary Representation of a Class is Structurally Correct OR Not.
That is JVM will Check whether .class File generated by Valid Compiler OR Not.i.ewhether .class File is Properly Formatted OR Not.
Internally Byte Code Verifier which is Part of ClassLoader Sub System is Responsible for this Activity.
If Verification Fails then we will get Runtime Exception Saying java. lang.VerifyError.
Preparation
In this phase, JVM will allocate Memory for Class Level Static variables and assign default values (Not Original Value).
Note: Original Value Assign into initialization part.
Resolution
It is the process of Replaced Symbolic References used by the loaded type with original References.
Symbolic References are Resolved into Direct References by searching through Method Area to Locate the Referenced Entity.
For Example;
In the above Program, There are Three Classes
- String Class
- Student Class
- Object Class (Object class is Parent Class of all java Classes)
For the above program ClassLoader SubSystem Loads Student.class, String.class and Object.class.
The Name of These Class Names is stored in the Constant Pool of Student Class.
In Resolution Phase these names are Replaced with Actual References from the method Area.
3.Initialization
In this Phase, All Static Variables will be assigned with Original Values and Static Blocks will be executed from top to bottom and from Parent to Child.
so summary of the ClassLoader subsystem is shown below figure.
Types Of ClassLoader
ClassLoader SubSystem Contains the Following three ClassLoaders.
- Bootstrap ClassLoader OR Primordial ClassLoader
- Extension ClassLoader
- Application ClassLoader
BootStrap ClassLoader
This ClassLoader is Responsible to load Classes from jdk\jre\lib.
All the core java API classes are present in rt.jar.which is present in this location only. Hence all API classes like(String, StringBuffer) will be loaded by BootStrap ClassLoader only.
It is implemented in Native languages like C and C++.
Extension ClassLoader
It is the Child of Bootstrap ClassLoader.
ThisClassLoader is Responsible for Load Classes from jdk\jre\lib\ext.
Application ClassLoader
It is the Child of Extension ClassLoader.
This ClassLoader is Responsible for Load Classes from Application Class Path (Current Working Directory).
It Internally Uses Environment Variable Class Path.
Let's see an example of All ClassLoader
For example,
lets Output of the Above program is
For String Class From Bootstrap Class-Path by Bootstrap ClassLoader Output is null because we see above BootStrap classpath is implemented in C and C++ so that Bootstrap ClassLoader is Not Java Object. Hence we are getting null in the 1st Case.
While Ketan class is part of Application ClassLoader because we can get Ketan.class file in the Current Working Directory.
Various Memory Area Of JVM
Whole Loading and Running a Java Program JVM required Memory to Store Several Things Like Byte Code, Objects, Variables, Etc.
Total JVM Memory is organized into the following 5 Categories:
- Method Area
- Heap Area OR Heap Memory
- Java Stacks Area
- PC Registers Area
- Native Method Stacks Area
Method Area
Method Area will be Created at the Time of JVM Start-Up.
It will be Shared by All Threads (Global Memory).
This Memory Area Need Not be Continuous.
Method area shows runtime constant pool.
Total Class Level Binary Information including Static Variables Stored in Method Area.
Heap Area
Programmer Point of View Heap Area is Consider an Important Memory Area.
Heap Area can be accessed by All Threads (Global OR Sharable Memory).
Heap Area Need Not be Continuous.
All Objects and corresponding Instance Variables will be stored in the Heap Area.
Every Array in Java is an Object and Hence Arrays Also will be stored in Heap Memory Only.
Stack Memory
For Every Thread, JVM will Create a Separate Runtime Stack.
Runtime Stack will be Created Automatically at the Time of Thread Creation.
All Method Calls and corresponding Local Variables, Intermediate Results will be stored in the Stack.
For Every Method Call, a Separate Entry will be added to the Stack and that Entry is Called Stack Frame. After completing that Method Call the corresponding Entry from the Stack will be removed.
The Data stored in the Stack can be accessed by Only the corresponding Thread and it is Not Available to Other Threads.
PC Register Area(Program Counter)
For Every Thread, a Separate PC Register will be Created at the Time of Thread Creation.
PC Registers contains Address of Current executing Instruction.
Once Instruction Execution Completes Automatically PC Register will be incremented to Hold Address of Next Instruction.
Native Method Stack
For Every Thread, JVM will Create a Separate Native Method Stack.
All Native Method Calls invoked by the Thread will be stored in the corresponding Native Method Stack.
Note:
Method Area and Heap Area are for JVM. Whereas Stack Area, PC Registers Area, and Native Method Stack Area are for Thread.
That is One Separate Heap for Every JVM
One Separate Method Area for Every JVM
One Separate Stack for Every Thread
One Separate PC Register for Every Thread
One Separate Native Method Stack for Every Thread
Summary:
Static Variables will be stored in Method Area.
Instance Variables will be stored in Heap Area.
Local Variables will be stored in Stack Area.
Execution Engine
This is the Central Component of JVM.
Execution Engine is Responsible to Execute Java Class Files.
Execution Engine contains 2 Components for executing Java Classes.
- Interpreter
- JIT Compiler
Interpreter
It is Responsible to Read Byte Code and Interpret (Convert) into Machine Code (Native Code) and Execute that Machine Code Line by Line.
The Problem with Interpreters is it Interpreters Every Time Even the Same Method Multiple Times. Which Reduces the Performance of the System.
To Overcome this Problem SUN People Introduced JIT Compilers in 1.1 Version.
JIT Compiler
The Main Purpose of JIT Compiler is to Improve Performance which is a disadvantage of java Interpreter.
Internally JIT Compiler Maintains a Separate Count for Every Method whenever JVM Come Across any Method Call.
First, that Method will be interpreted normally by the Interpreter, and JIT Compiler Increments the corresponding Count Variable.
This process will be continued for Every Method.
Once if any Method Count Reaches Threshold (The Starting Point for a New State) Value, then JIT Compiler Identifies that Method Repeatedly used Method.
Immediately JIT Compiler Compiles that Method and Generates the corresponding Native Code. Next Time JVM Come Across that Method Call then JVM Directly Uses Native Code and Executes it Instead of interpreting Once Again. So that Performance of the System will be Improved.
The Threshold Count Value varied from JVM to JVM.
Some Advanced JIT Compilers will Re-compile generated Native Code if Count Reaches Threshold Value Second Time So that More optimized Machine Code will be generated.
Summary of Execution Engine
JVM Interprets Total Program Line by Line at least Once.
JIT Compilation is Applicable Only for Repeatedly invoked Methods. But Not for Every Method.