Assignment 3
Assignment 3
The Java Development Kit (JDK) is a cross-platformed software development environment that offers a
collection of tools and libraries necessary for developing Java-based software applications and applets. It is a
core package used in Java, along with the JVM and the JRE (Java Runtime Environment).
Beginners often get confused with JRE and JDK, if you are only interested in running Java programs on your
machine then you can easily do it using Java Runtime Environment. However, if you would like to develop a
Java-based software application then along with JRE you may need some additional necessary tools, which is
called JDK
he JDK has a private Java Virtual Machine (JVM) and a few other resources necessary for the development of
a Java Application.
JDK contains:
Java Runtime Environment (JRE),
An interpreter/loader (Java),
A compiler (javac),
An archiver (jar) and many more.
Working of JDK
The JDK enables the development and execution of Java programs. Consider the following process:
Java Source File (e.g., Example.java): You write the Java program in a source file.
Compilation: The source file is compiled by the Java Compiler (part of JDK) into bytecode,
which is stored in a .class file (e.g., Example.class).
Execution: The bytecode is executed by the JVM (Java Virtual Machine), which interprets the
bytecode and runs the Java program
The JRE 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.
Working of JRE
When you run a Java program, the following steps occur:
Class Loader: The JRE’s class loader loads the .class file containing the bytecode into memory.
Bytecode Verifier: The bytecode verifier checks the bytecode for security and correctness.
Interpreter: The JVM interprets the bytecode and executes the program.
Execution: The program executes, making calls to the underlying hardware and system resources
as needed.
JVM(Java Virtual Machine) runs Java applications as a run-time engine. JVM is the one that calls
the main method present in a Java code. JVM is a part of JRE(Java Runtime Environment).
Java applications are called WORA (Write Once Run Anywhere). This means a programmer can develop
Java code on one system and expect it to run on any other Java-enabled system without any adjustment. This
is all possible because of JVM.
When we compile a .java file, .class files(contains byte-code) with the same class names present in .java file
are generated by the Java compiler. This .class file goes into various steps when we run it. These steps
together describe the whole JVM.
Loading:
The class loader reads the ".class" file, generates binary data, and stores it in the method area. It saves details
like the class name, parent class, whether it's a class, interface, or enum, and information about methods and
variables. After loading, the JVM creates a Class object in the heap memory that represents this file. This Class
object can be used to get information about the class, such as its name, parent class, and methods, using the
getClass() method.
Linking:
This process involves verification, preparation, and resolution.
Verification checks if the ".class" file is correctly formatted. If not, a runtime exception
(java.lang.VerifyError) occurs.
Preparation allocates memory for static variables and initializes them to default values.
Resolution replaces symbolic references with direct references by searching the method area.
Initialization:
In this phase, static variables are assigned values defined in the code and static blocks, executed in order from
top to bottom.
Bootstrap Class Loader: Loads core Java API classes from the JAVA_HOME/lib directory. It is
implemented in native code.
Extension Class Loader: Loads classes from the JAVA_HOME/jre/lib/ext directory or specified by
java.ext.dirs. It is implemented in Java.
System/Application Class Loader: Loads classes from the application classpath defined by
java.class.path. It is also implemented in Java.
2. Class Loaders
There are three main types of class loaders:
Bootstrap Class Loader: Loads core Java API classes; not a Java object.
Extension Class Loader: Loads classes from extension directories; implemented in Java.
System/Application Class Loader: Loads classes from the application classpath; also implemented in
Java.
3. JVM Memory Areas
Method Area: Stores class-level information, including class names and static variables.
Heap Area: Stores all object information; there’s one heap area per JVM.
Stack Area: Each thread has a runtime stack for method calls and local variables; it is not shared.
PC Registers: Store the address of the current instruction for each thread; separate for each thread.
Native Method Stacks: Each thread has a separate stack for native method information.
4. Execution Engine
The Execution Engine executes the ".class" (bytecode) by reading it line by line and using information from
memory areas. It consists of three parts:
Interpreter: Interprets bytecode line by line, but can be slow for repeated method calls.
Just-In-Time Compiler (JIT): Compiles bytecode into native code to improve efficiency for repeated
calls.
Garbage Collector: Destroys unreferenced objects.
5. Java Native Interface (JNI)
JNI is an interface that allows interaction with native libraries (C, C++) for execution, enabling the JVM to call
and be called by C/C++ libraries.
Java Virtual Machine (JVM) is mainly written in C, C++, and Assembly, depending on the implementation,
with HotSpot JVM being the most widely used.
C and C++ provide low-level system access, which is crucial for memory management and performance
optimizations, offering faster execution than higher-level languages. Key JVM components like Garbage
Collection (GC), Thread Management, and Just-In-Time (JIT) Compilation require efficient low-level
programming.
Specific parts of the JVM written in C/C++ include the Class Loader Subsystem, Memory Management (Heap,
Stack, Method Area), Garbage Collector implementation, JIT Compiler, and Java Native Interface (JNI). The
HotSpot JVM’s memory allocation and garbage collection are implemented in C++ for enhanced performance.
Assembly language is used for platform-specific optimizations, enabling direct interaction with CPU registers
and efficient thread scheduling. Different OS and CPU architectures necessitate different Assembly instructions,
so JVM implementations use tailored assembly optimizations.
Parts of the JVM that utilize Assembly include Thread scheduling, efficient CPU instruction execution (JIT
compiler optimizations), and atomic operations for low-level memory handling. In HotSpot JVM, Assembly is
integral to JIT Compilation for generating optimized machine code across various CPU architectures.
Java itself is employed for the standard library and some JVM tools, as the Java Standard Library (JDK) is
predominantly written in Java. Components such as debugging tools and monitoring utilities are implemented in
Java.
Sections of the JVM written in Java encompass Standard Java APIs (Collections, Streams), JVM Management
Tools (JConsole, jstat, jmap), and the Java Class Library (java.lang, java.util).
Different JVM implementations mix C, C++, Assembly, and Java. HotSpot JVM primarily consists of C++,
some Assembly, and Java for libraries, while OpenJ9 JVM is largely in C and C++, with some Java. GraalVM
is mainly in Java and compiles Java to native code, and Dalvik/ART (Android JVMs) primarily employs C++
and some Assembly.
In summary, JVM mainly relies on C and C++ for core implementation (memory management, GC, JIT
Compiler, threading), uses Assembly for low-level CPU optimizations (thread scheduling, atomic operations),
and Java for standard libraries and JVM monitoring tools.