JDK (Java Development Kit) is a Kit that provides the environment to develop and execute(run) the Java program. JDK is a kit(or package) that includes two things
- Development
     Tools (to provide an environment to develop your java programs)
- JRE (to execute your java program).
JRE (Java Runtime Environment) is an installation package that provides an environment to only run(not develop) the java program(or application)onto your machine. JRE is only used by those who only want to run Java programs that are end-users of your system.
JVM (Java Virtual
Machine) is a very important part of both JDK and JRE because it is
contained or inbuilt in both. Whatever Java program you run using JRE or JDK
goes into JVM and JVM is responsible for executing the java program line by
line, hence it is also known as an interpreter.
- JVM
     is responsible for converting the byte code to machine code.
- JVM takes (.class) files and
     executes it by managing the memory
- JVM
     loads, verifies and executes the code and provides the runtime environment
- JVM
     plays a major role in java memory management
JVM Architecture
1) Classloader
Classloader is a subsystem of JVM which is
used to load class files. Whenever we run the java program, it is loaded first
by the classloader. 
The classLoading mechanism consists of
three main steps as follows.
- Loading
- Linking
- Initialization
Loading
Whenever JVM loads a file, it will load
and read,
- Fully
     qualified class name
- Variable
     information (instance variables)
- Immediate
     parent information
- Whether
     class or interface or enum
There are three built-in classloaders in
Java.
- Bootstrap
     ClassLoader:
     This is the first classloader which is the super class of Extension
     classloader. It loads the rt.jar file which contains all
     class files of Java Standard Edition like java.lang package classes,
     java.net package classes, java.util package classes, java.io package
     classes, java.sql package classes etc.
- Extension
     ClassLoader:
     This is the child classloader of Bootstrap and parent classloader of
     System 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.
 Linking
This is the process of linking the data in
the class file into the memory area. It begins with verification to
ensure this class file and the compiler.
Verification: This phase
checks the structural correctness of the .class file by checking it
against a set of constraints or rules. If verification fails for some reason,
we get a VerifyException.
For example, if the code has been built using
Java 11, but is being run on a system that has Java 8 installed, the
verification phase will fail.
Prepare – For all static
variables memory will be allocated and assigned with default values.
Resolve – All symbolic memory
references are replaced with the original references from Method Area.
Initialization
This is the final phase of ClassLoading;
here, all static variables will be assigned with the original values,
and the static block will be executed
JVM Memory Areas
- Method
     area: All the class level data such as the run-time
     constant pool, field, and method data, and the code for methods and
     constructors, are stored here. 
If the memory
available in the method area is not sufficient for the program startup, the JVM
throws an OutOfMemoryError.
For example, assume that you have the following class
definition:
public class Employee {
 
private String name;
 
private int age;
 
public Employee(String name, int age) {
   
this.name = name;
   
this.age = age;
  }
}
In this code example, the field level data such
as name and age and the constructor details are loaded into
the method area.
The method area is created on the virtual machine
start-up, and there is only one method area per JVM.
- Heap
     area: Information
     of all objects is stored in the heap area. There is also one Heap Area per
     JVM. It is also a shared resource.
For example assume that you are declaring
the following instance:
Employee employee = new Employee();
In this
code example, an instance of Employee is created and loaded into the heap area.
The heap is
created on the virtual machine start-up, and there is only one heap area per
JVM.
- Stack
     area: For
     every thread, JVM creates one run-time stack which is stored here. After a
     thread terminates, its run-time stack will be destroyed by JVM. It is not
     a shared resource.
- PC
     Registers: The
     JVM supports multiple threads at the same time. Each thread has its own PC
     Register to hold the address of the currently executing JVM instruction.
     Once the instruction is executed, the PC register is updated with the next
     instruction.
- Native
     method stacks: The
     JVM contains stacks that support native methods. These
     methods are written in a language other than the Java, such as C and C++.
     For every new thread, a separate native method stack is also allocated
Execution Engine 
Execution engine executes the “.class” (bytecode).
It reads the byte-code line by line, uses data and information present in
various memory area and executes instructions. It can be classified into three
parts:
- Interpreter: It
     interprets the bytecode line by line and then executes. The disadvantage
     here is that when one method is called multiple times, every time
     interpretation is required.
- Just-In-Time
     Compiler(JIT) : It is used to increase the efficiency of
     an interpreter. It compiles the entire bytecode and changes it to native
     code so whenever the interpreter sees repeated method calls, JIT provides
     direct native code for that part so re-interpretation is not required,
     thus efficiency is improved.
- Garbage
     Collector:
     The Garbage Collector (GC) collects and removes unreferenced objects from
     the heap area. It is the process of reclaiming the runtime unused memory
     automatically by destroying them.’
Garbage
collection makes Java memory efficient because it removes the unreferenced
objects from heap memory and makes free space for new objects. It involves two
phases:
- Mark - in this
     step, the GC identifies the unused objects in memory
- Sweep - in this
     step, the GC removes the objects identified during the previous phase
Garbage
Collections is done automatically by the JVM at regular intervals and does not
need to be handled separately. It can also be triggered by
calling System.gc(), but the execution is not guaranteed.
The
JVM contains 3 different types of garbage collectors:
- Serial GC - This is
     the simplest implementation of GC, and is designed for small applications
     running on single-threaded environments. It uses a single thread for
     garbage collection. When it runs, it leads to a "stop the world"
     event where the entire application is paused. The JVM argument to use
     Serial Garbage Collector is -XX:+UseSerialGC
- Parallel GC - This is
     the default implementation of GC in the JVM, and is also known as
     Throughput Collector. It uses multiple threads for garbage collection, but
     still pauses the application when running. The JVM argument to use
     Parallel Garbage Collector is -XX:+UseParallelGC.
- Garbage First
     (G1) GC - G1GC
     was designed for multi-threaded applications that have a large heap size
     available (more than 4GB). It partitions the heap into a set of equal size
     regions, and uses multiple threads to scan them. G1GC identifies the
     regions with the most garbage and performs garbage collection on that
     region first. The JVM argument to use G1 Garbage Collector
     is -XX:+UseG1GC
Note: There is another type of garbage collector called Concurrent Mark Sweep (CMS) GC. However, it has been deprecated since Java 9 and completely removed in Java 14 in favour of G1GC.
Java
Native Interface (JNI)
At
times, it is necessary to use native (non-Java) code (for example, C/C++). This
can be in cases where we need to interact with hardware, or to overcome the
memory management and performance constraints in Java. Java supports the
execution of native code via the Java Native Interface (JNI).
- ClassNotFoundExcecption - This
     occurs when the Class Loader is trying to load classes
     using Class.forName(), ClassLoader.loadClass() or ClassLoader.findSystemClass() but
     no definition for the class with the specified name is found.
- NoClassDefFoundError - This
     occurs when a compiler has successfully compiled the class, but the Class
     Loader is not able to locate the class file at the runtime.
- OutOfMemoryError - This
     occurs when the JVM cannot allocate an object because it is out of memory,
     and no more memory could be made available by the garbage collector.
- StackOverflowError - This
     occurs if the JVM runs out of space while creating new stack frames while
     processing a thread.



 
No comments:
Post a Comment