Exploring Java Architecture: A Guide to Java's Core, JVM and JDK Architecture
Updated on Jan 10, 2025 | 26 min read | 14.9k views
Share:
For working professionals
For fresh graduates
More
Updated on Jan 10, 2025 | 26 min read | 14.9k views
Share:
Table of Contents
Java architecture forms the core of one of the most widely used programming languages in the world. It is designed to provide a platform-independent, secure, and efficient environment for application development.
Java architecture is built around the Java Virtual Machine (JVM), which executes Java bytecode efficiently. It also includes the Java Development Kit (JDK) for development tools and libraries, and the Java Runtime Environment (JRE) for running applications.
Understanding how these components work together is crucial for developers aiming to build robust applications. In this blog, you’ll explore Java architecture in detail, including how the JVM operates and the structure of the JDK architecture in Java. Let’s dive in!
Java architecture is a framework that allows Java applications to run on any device or platform. It consists of three main components. The Java Virtual Machine (JVM) executes bytecode, the Java Development Kit (JDK) provides development tools, and the Java Runtime Environment (JRE) runs Java applications.
Below are the key roles of the JVM architecture in Java that make it indispensable.
By combining these functions, the JVM architecture in Java guarantees consistency, security, and high performance, forming the bedrock of the JDK architecture in Java.
Java Architecture: Interaction Between JVM, JDK, and JRE
To better understand the interplay between the core components of Java, the following diagram illustrates the architecture, highlighting the roles and interactions of the JVM, JDK, and JRE.
Ready to learn powerful languages like Java? Start your journey with upGrad’s online data science courses today!
To truly understand the power of the JVM architecture in the Java programming language, you need to dive deeper into its core components. Each part works together to execute Java programs seamlessly, ensuring efficiency and security.
Below are the key components of the JVM architecture in Java and their roles in execution.
Each component contributes to the smooth execution of your program, making the JVM architecture in Java a marvel of efficiency and innovation. Below is a simple demonstration to clarify how these components interact during execution.
Code Example: Class Loading, Memory Allocation, and Bytecode Execution
Objective: This example demonstrates class loading, memory allocation, and how bytecode is executed step-by-step in the JVM.
Code Snippet:
public class JVMExample {
static int staticVariable = 10; // Static variable initialization
public static void main(String[] args) {
int localVariable = 20; // Local variable in the stack
ExampleObject obj = new ExampleObject(30); // Object allocation in the heap
System.out.println("Static Variable: " + staticVariable);
System.out.println("Local Variable: " + localVariable);
System.out.println("Object Variable: " + obj.instanceVariable);
}
}
class ExampleObject {
int instanceVariable;
ExampleObject(int value) {
this.instanceVariable = value; // Initialization in the heap
}
}
Output:
Static Variable: 10 // Initialized in the Method Area during class loading.
Local Variable: 20 // Stored in the Java Stack as part of the main method's frame.
Object Variable: 30 // Allocated in the Heap as part of the ExampleObject instance.
Explanation:
Each component operates in harmony, demonstrating the power of the JVM architecture in Java.
Also Read: Scope of a Variable In Java [With Coding Example]
Now, let's take a closer look at the specific roles of the Class Loader Subsystem, Runtime Data Areas, and Execution Engine in the JVM architecture in Java.
The Class Loader Subsystem is your program’s entry point into the JVM architecture in Java. It loads, links, and initializes class files, ensuring your code runs without any hiccups.
Below are the main functions of the Class Loader Subsystem.
Code Example: Static variable initialization during class loading
Code Snippet:
public class ClassLoaderExample {
static int staticVar = 42; // Initialized during class loading
public static void main(String[] args) {
System.out.println("Static Variable: " + staticVar);
}
}
Output:
Static Variable: 42
Explanation:
Also Read: How to Add Two Numbers in Java?
The Runtime Data Areas manage memory dynamically, ensuring efficient execution of Java programs. Below are its primary components.
Code Example: Memory allocation in the stack and heap
Code Snippet:
public class MemoryExample {
public static void main(String[] args) {
int number = 5; // Stack memory
MemoryObject obj = new MemoryObject(15); // Heap memory
System.out.println("Number: " + number);
System.out.println("Object Value: " + obj.value);
}
}
class MemoryObject {
int value;
MemoryObject(int value) {
this.value = value;
}
}
Output:
Number: 5
Object Value: 15
Explanation:
The Execution Engine is the core of the JVM architecture in Java, responsible for converting bytecode into machine code for execution. Below are its main components.
Code Example: JIT Compilation and Garbage Collection
Code Snippet:
public class ExecutionExample {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
System.out.println("Iteration: " + i); // Optimized by JIT
}
ExecutionExample obj = new ExecutionExample(); // Allocated in heap
obj = null; // Ready for garbage collection
}
}
Output:
Iteration: 0
Iteration: 1
Iteration: 2
Iteration: 3
Iteration: 4
Explanation:
The collaboration between these components makes the JVM architecture in Java a robust, reliable, and efficient system for executing Java programs.
In Java development, the Java Virtual Machine (JVM), Java Development Kit (JDK), and Java Runtime Environment (JRE) play crucial roles in ensuring efficient application development and execution.
Here's how they work together.
Workflow Diagram: From Writing Code to Execution
The overall workflow for creating and running Java applications typically involves: writing your Java code → compiling it using the JDK architecture in Java → running it through the JRE and the JVM.
Also Read: How to Code, Compile, and Run Java Projects
Now that you understand the interplay of JVM, JDK, and JRE, let's dive into the detailed workflow of how these components come together in action.
The workflow from writing Java code to executing it can be broken down into a series of steps. Each component plays its part in the development and execution of your application. Here’s the breakdown.
For example, if you want to write a simple "Hello World" program, you would:
This workflow ensures that Java programs are portable and can run on any machine with a compatible JVM.
Also Read: Coding vs. Programming: A Never Ending Debate
Now that you know how the JVM, JDK, and JRE work together, let's examine how the JVM handles memory management during the execution of a Java program.
The JVM uses a dynamic class loading mechanism to load and prepare classes for execution, ensuring that only the necessary classes are loaded into memory.
Key points:
This mechanism ensures that your Java programs run efficiently, only loading what is necessary and resolving dependencies dynamically.
Code Example: Below is a simple custom class loader demonstrating the class loading process.
Code Snippet:
import java.net.*;
import java.io.*;
public class MyClassLoader extends ClassLoader {
public Class<?> findClass(String name) throws ClassNotFoundException {
try {
byte[] classData = loadClassData(name);
return defineClass(name, classData, 0, classData.length);
} catch (IOException e) {
throw new ClassNotFoundException(name, e);
}
}
private byte[] loadClassData(String name) throws IOException {
InputStream inputStream = new FileInputStream(name + ".class");
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);
return buffer;
}
public static void main(String[] args) throws Exception {
MyClassLoader loader = new MyClassLoader();
Class<?> clazz = loader.loadClass("HelloWorld");
System.out.println("Class Loaded: " + clazz.getName());
}
}
Output:
Class Loaded: HelloWorld // Ensure that the HelloWorld.class file is in the same directory for the code to work correctly.
Explanation:
Also Read: 10 Best Computer Programming Courses To Get a Job in 2025
Now, let's explore the architecture of the JRE and JDK architecture in Java.
The JDK and JRE are essential components of the Java environment, each providing a different set of tools and capabilities. Here’s the breakdown.
Code Snippet:
public class Example {
public static void main(String[] args) {
System.out.println("Hello, Java!");
}
}
Output:
Hello, Java!
Explanation:
Here’s a quick comparison between JDK and JRE to help you understand their features and roles.
Feature |
JDK (Java Development Kit) |
JRE (Java Runtime Environment) |
Purpose |
Toolset for developing Java applications |
Environment for running Java applications |
Includes |
Compiler (javac), Debugger, Libraries, JVM |
JVM, Core Libraries |
Usage |
Used by developers to create Java programs |
Used by end users to run Java applications |
Components |
Includes JRE and additional development tools |
Only includes JVM and essential libraries |
This should help clarify the distinctions between JDK and JRE in Java, and how each is used within the overall Java architecture.
Also Read: Top 20 Highest Paying Programming Languages In India
upGrad’s Exclusive Software and Tech Webinar for you –
SAAS Business – What is So Different?
Memory management is a critical part of Java architecture, ensuring efficient allocation and garbage collection. It ensures efficient memory usage by allocating and deallocating memory for objects and variables.
Here’s the breakdown.
Visualizing Memory Allocation Diagram: Heap and Stack Memory Areas
To better understand the allocation and management of memory in a program, let’s explore the diagram below, which provides a clear visual representation of the heap and stack memory areas.
Also Read: Why is Java Platform Independent Language?
Now, let’s take a closer look at the Heap Space in the JVM, and how it manages dynamic memory allocation.
Heap space is a critical component of Java memory management. It is divided into different generations that handle newly created and long-lived objects separately, improving performance. Here are the two generations of heap space.
Heap space plays a vital role in managing the memory needs of Java applications, ensuring that objects are efficiently allocated and deallocated.
Understanding Heap Space Structure: A Detailed Diagram
To gain a clearer understanding, let’s delve into the following diagram, which illustrates the structure of heap space.
Also Read: Top 10 Java Books to Read to Improve Your Knowledge
Now, let's dive into the role of Stack Memory in the JVM, and how it supports method execution.
Each thread in the Java architecture has its own stack memory. Stack memory is essential for method execution and local variable storage.
Key points:
Also Read: Java Developer Salary: What to Expect in India 2025
Stack memory is crucial for the efficient operation of Java programs, ensuring that method calls and local variables are handled without manual intervention.
A Step-by-Step Illustration of Stack Frames in Execution
To better understand how method calls work, let's explore how stack frames are illustrated during the execution of these calls, highlighting the step-by-step process and their impact on the program's flow.
Next, let's explore Garbage Collection in the JVM, which ensures that memory is automatically reclaimed and reused.
Garbage collection is a critical part of the JVM architecture in Java, ensuring efficient memory management by automatically reclaiming memory occupied by unused objects. It works seamlessly within the broader JVM framework, particularly in the runtime data areas like the heap, where objects are allocated.
By handling memory deallocation automatically, garbage collection allows you to focus on writing code without worrying about manual memory management.
Key points:
Garbage collection plays a vital role in maintaining memory efficiency in Java applications.
Garbage Collection Process in JVM: A Flowchart
Let's explore the garbage collection process in the JVM, illustrated through a flowchart that outlines each step involved in memory management and object cleanup.
Next, let's look at the Class Loading Mechanism in the JVM, a dynamic process that prepares classes for execution.
Optimizing JVM performance is essential for ensuring that your Java applications run faster and more efficiently. By focusing on key areas of the Java architecture, you can unlock significant improvements in both speed and resource usage.
Optimization isn't just about writing good code; it’s about tailoring the environment in which your code runs to maximize its potential.
Here are several strategies to enhance JVM performance.
In practice, these JVM optimization strategies work in unison to create an environment that ensures your code runs with maximum efficiency. By understanding these techniques, you can apply them to your own Java projects, ensuring that the Java architecture is leveraged to its full potential.
Code Example: Below is a Java program that calculates the sum of an array of numbers. You’ll look at how JIT compilation impacts performance in such simple but frequently used methods.
Code Snippet:
public class JITOptimizationExample {
public static int calculateSum(int[] numbers) {
int sum = 0;
for (int number : numbers) {
sum += number;
}
return sum;
}
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
long startTime = System.nanoTime();
System.out.println("Sum: " + calculateSum(numbers));
long endTime = System.nanoTime();
System.out.println("Execution time: " + (endTime - startTime) + " nanoseconds");
}
}
Output:
Sum: 55
Execution time: 23425 nanoseconds
Explanation:
When optimizing JVM performance, the key lies in understanding how each optimization works within the Java architecture. It’s about fine-tuning each component so that, collectively, they provide the most efficient execution possible.
By focusing on JIT, Hotspot, and memory management, you can significantly enhance the performance of any Java application, regardless of its complexity.
To achieve optimal performance in real-world applications, understanding and monitoring the behavior of your JVM is critical. Tools like JConsole and VisualVM provide deep insights into the performance and health of your Java applications, enabling you to identify bottlenecks and fine-tune the JVM for better efficiency.
JConsole (Java Monitoring and Management Console) is a built-in tool provided with the JDK, designed to monitor and manage Java applications.
Features:
Usage Example: To use JConsole, start your Java application with the -Dcom.sun.management.jmxremote flag. Open JConsole and connect it to the running application to observe its metrics in real time.
VisualVM is a powerful tool that provides detailed profiling and debugging capabilities, going beyond what JConsole offers.
Features:
Usage Example: Launch VisualVM and attach it to your Java process. Use the Profiler tab to analyze method execution times and memory usage, or inspect thread states to diagnose performance issues.
Here’s why JVM monitoring tools are essential.
By leveraging tools like JConsole and VisualVM, developers can gain a comprehensive understanding of how their applications interact with the JVM. Monitoring these metrics in production or during development ensures that optimization efforts are targeted and effective, leading to faster, more reliable applications.
Java’s architecture is designed not only to prevent unauthorized access and malicious behavior but also to mitigate several common security threats that plague modern software systems. These threats include SQL injection, buffer overflow attacks, and other vulnerabilities that can compromise the integrity and confidentiality of an application.
Below are some of the key security challenges Java addresses:
SQL injection occurs when malicious code is inserted into an SQL query, potentially allowing attackers to view, modify, or delete data in a database. Java, through its secure coding practices and frameworks like JDBC and Hibernate, provides robust protection against this type of attack.
Here’s how Java protects against SQL injection.
Buffer overflow attacks occur when more data is written to a buffer than it can handle, leading to the overwriting of adjacent memory. This can corrupt data or allow attackers to execute arbitrary code. Java’s memory management model, coupled with the JVM’s automatic bounds checking, eliminates the possibility of buffer overflows.
Here’s how Java prevents buffer overflow attacks.
Cross-site scripting (XSS) attacks occur when an attacker injects malicious scripts into web pages that are viewed by other users. Java provides mechanisms to mitigate XSS vulnerabilities in web applications.
Here’s how Java mitigates XSS attacks.
Deserialization attacks occur when malicious data is deserialized into an object, which can be exploited to execute arbitrary code or perform malicious actions. Java provides safeguards to address this issue.
Here’s how Java handles deserialization safely.
Privilege escalation attacks occur when a user gains elevated access rights, often due to poor security design. Java’s security manager and Access Control Lists (ACLs) help mitigate these risks.
Here’s how java prevents privilege escalation.
The JVM’s security features, like class verification, sandboxing, and runtime security checks, work together to ensure the integrity of your application.
Developers can enhance security further by adopting secure coding practices, utilizing frameworks and libraries that address these specific threats, and taking advantage of Java’s built-in security mechanisms.
Understanding and leveraging these security features will help you build more secure Java applications that can withstand common vulnerabilities and malicious attacks.
Code Example: Below is a simple Java program where a malformed bytecode could potentially be dangerous if not verified. The JVM ensures that such bytecode is not executed.
Code Snippet:
public class SecurityExample {
public static void main(String[] args) {
System.out.println("This is a secure JVM example!");
}
}
Output:
This is a secure JVM example!
Explanation:
The JVM’s built-in security features, such as class verification and sandboxing, form the foundation of Java's secure execution environment. These safeguards ensure that no matter where the Java application runs, it remains protected from malicious actors.
By understanding these mechanisms, you can have confidence in the JDK architecture in Java, knowing that every program you run is under the protective umbrella of the JVM’s security features. This level of protection helps mitigate risks and prevents common vulnerabilities.
Also Read: Careers in Java: How to Make a Successful Career in Java in 2025
Maximizing the efficiency of Java architecture requires careful attention to several factors that directly influence the performance and stability of your Java applications. By adhering to best practices, you ensure that your applications run smoothly, consume fewer resources, and scale effectively.
Optimizing JVM usage is about making the most of its features without overloading the system. Here are key best practices to follow for optimal JVM performance.
These practices, rooted in the Java architecture, ensure that your applications run at peak performance while minimizing wasted resources. A deep understanding of Java architecture and JDK architecture in Java empowers you to harness the full potential of the JVM, maximizing both stability and speed.
Code Example: Below is a Java program that configures the JVM to use a different garbage collection algorithm for optimized memory usage.
Code Snippet:
public class GarbageCollectionExample {
public static void main(String[] args) {
System.out.println("Starting JVM with optimized garbage collection.");
// Allocate a large array to simulate memory usage
int[] largeArray = new int[10000000];
// Nullify the reference to simulate object no longer needed
largeArray = null;
// Request garbage collection manually (not recommended in production)
System.gc();
System.out.println("Garbage collection triggered!");
}
}
Output:
Starting JVM with optimized garbage collection.
Garbage collection triggered!
Clarification: The System.gc() method in this code only suggests that the JVM perform garbage collection. It does not guarantee that garbage collection will occur immediately, as the JVM decides the timing based on its internal optimization mechanisms.
Disclaimer: Avoid using System.gc() in production environments unless absolutely necessary. Explicit garbage collection calls can disrupt the JVM's optimized memory management process and potentially degrade application performance. It's best to rely on the JVM's built-in garbage collection strategies to handle memory efficiently.
Explanation:
By adopting these best practices, you can make better use of architecture in Java. It’s not about making drastic changes but about small, strategic adjustments that enhance performance.
With an understanding of JDK architecture in Java and how the JVM operates, you can fine-tune your environment for efficient execution, memory management, and overall system stability. These best practices not only optimize performance but also ensure that your Java applications are prepared for the challenges of the real world.
Also Read: Top 8 Reasons Why Java Is So Popular With Developers in 2024
To truly stand out in JVM and Java architecture, you need a comprehensive learning path that equips you with the right knowledge and technical skills. upGrad offers a range of free courses designed to help you understand and master the complexities of JVM and Java architecture.
Below are some of upGrad’s free courses with key focus areas.
Course Title |
Key Focus Areas |
Core Java Basics | Java fundamentals, Java syntax, and core concepts of JVM architecture in Java. |
JavaScript Basics | JavaScript basics with an understanding of JavaScript and JVM architecture's interaction. |
Object-Oriented Principles in Java | Deep dive into object-oriented principles and their role within Java architecture and JVM. |
Boost your career with our popular Software Engineering courses, offering hands-on training and expert guidance to turn you into a skilled software developer.
Master in-demand Software Development skills like coding, system design, DevOps, and agile methodologies to excel in today’s competitive tech industry.
Stay informed with our widely-read Software Development articles, covering everything from coding techniques to the latest advancements in software engineering.
Get Free Consultation
By submitting, I accept the T&C and
Privacy Policy
India’s #1 Tech University
Executive PG Certification in AI-Powered Full Stack Development
77%
seats filled
Top Resources