
Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:
Once the early-adopter seats are all used, the price will go up and stay at $33/year.
Last updated: January 8, 2024
In this article, we’ll discuss differences between JVM, JRE, and JDK by considering their components and uses.
Java Virtual Machine (JVM) is an implementation of a virtual machine which executes a Java program.
The JVM first interprets the bytecode. It then stores the class information in the memory area. Finally, it executes the bytecode generated by the java compiler.
It is an abstract computing machine with its own instruction set and manipulates various memory areas at runtime.
Components of the JVM are:
Initial tasks of the JVM includes loading, verifying and linking the bytecode. Class loaders handle these tasks.
We have a detailed article specifically on class loaders.
The JVM defines various memory areas to execute a Java program. These are used during runtime and are known as run-time data areas. Some of these areas are created on the JVM start-up and destroyed when the JVM exits while some are created when a thread is created and destroyed when a thread exits.
Let’s consider these areas one by one:
Method Area
Basically, method area is analogous to the storage area for compiled code. It stores structures such as run-time constant pool, field and method data, the code for methods and constructors as well as fully qualified class names. The JVM stores these structure for each and every class.
The method area, also known as permanent generation space (PermGen), is created when the JVM starts up. The memory for this area does not need to be contiguous. All the JVM threads share this memory area.
Heap Area
The JVM allocates the memory for all the class instances and arrays from this area.
Garbage Collector (GC) reclaims the heap memory for objects. Basically, GC has three phases to reclaim memory from objects viz. two minor GC and one major GC.
The heap memory has three portions:
JVM creates heap area as soon as it starts up. All the threads of the JVM share this area. The memory for the heap area does not need to be contiguous.
Stack area
Stores data as frames and each frame stores local variables, partial results and nested method calls. JVM creates the stack area whenever it creates a new thread. This area is private for each thread.
Each entry in the stack is called Stack Frame or Activation record. Each frame contains three parts:
The memory for the JVM stack does not need to be contiguous.
PC Registers
Each JVM thread has a separate PC Register which stores the address of the currently executing instruction. If the currently executing instruction is a part of the native method then this value is undefined.
Native method stacks
Native methods are those which are written in languages other than Java.
JVM provides capabilities to call these native methods. Native method stacks are also known as “C stacks”. They store the native method information. Whenever the native methods are compiled into machine codes, they usually use a native method stack to keep track of their state.
The JVM creates these stacks whenever it creates a new thread. And thus JVM threads don’t share this area.
Execution engine executes the instructions using information present in the memory areas. It has three parts:
Interpreter
Once classloaders load and verify bytecode, the interpreter executes the bytecode line by line. This execution is quite slow. The disadvantage of the interpreter is that when one method is called multiple times, every time new interpretation is required.
However, the JVM uses JIT Compiler to mitigate this disadvantage.
Just-In-Time (JIT) Compiler
JIT compiler compiles the bytecode of the often-called methods into native code at run-time. Hence it is responsible for the optimization of the Java programs.
JVM automatically monitors which methods are being executed. Once a method becomes eligible for JIT compilation, it is scheduled for compilation into machine code. This method is then known as a hot method. This compilation into machine code happens on a separate JVM thread.
As a result, it does not interrupt the execution of the current program. After compilation into machine code, it runs faster.
Garbage Collector
Java takes care of memory management using Garbage Collection. It’s a process of looking at heap memory, identifying which objects are in use and which are not, and finally deleting unused objects.
GC is a daemon thread. It can be called explicitly using System.gc() method, however, it won’t be executed immediately and the JVM decides when to invoke GC.
It acts as an interface between the Java code and the native (C/C++) libraries.
There are situations in which Java alone doesn’t meet the needs for your application, for example, implementing a platform-dependent feature.
In those cases, we can use JNI to enable the code running in the JVM to call. Conversely, it enables native methods to call the code running in the JVM.
These are platform specific libraries and contains the implementation of native methods.
Java Runtime Environment (JRE) is a bundle of software components used to run Java applications.
Core components of the JRE include:
We discussed the JVM in the above section. Here we will focus on the core classes and support files.
We’ll find bootstrap classes under jre/lib/. This path is also known as the bootstrap classpath. It includes:
Bootstrap ClassLoader loads these classes when the JVM starts up.
We can find extension classes in jre/lib/extn/ which acts as a directory for extensions to the Java platform. This path is also known as extension classpath.
It contains JavaFX runtime libraries in jfxrt.jar and locale data for java.text and java.util packages in localedata.jar. Users can also add custom jars into this directory.
Java platform uses these property settings to maintain its configuration. Depending on their usage they are located in different folders inside /jre/lib/. These include:
Apart from the above-mentioned files and classes, JRE also contains files for other matters:
Java Development Kit (JDK) provides environment and tools for developing, compiling, debugging, and executing a Java program.
Core components of JDK include:
We discussed the JRE in the above section.
Now, we’ll focus on various development tools. Let’s categorize these tools based on their usage:
These tools lay the foundation of the JDK and are used to create and build Java applications. Among these tools, we can find utilities for compiling, debugging, archiving, generating Javadocs, etc.
They include:
These include key and certificate management tools that are used to manipulate Java Keystores.
A Java Keystore is a container for authorization certificates or public key certificates. Consequently, it is often used by Java-based applications for encryption, authentication, and serving over HTTPS.
Also, they help to set the security policies on our system and create applications which can work within the scope of these policies in the production environment. These include:
Some security tools also help in managing Kerberos tickets.
Kerberos is a network authentication protocol.
It works on the basis of tickets to allow nodes communicating over a non-secure network to prove their identity to one another in a secure manner:
Internationalization is the process of designing an application so that it can be adapted to various languages and regions without engineering changes.
For this purpose, the JDK brings native2ascii. This tool converts a file with characters supported by JRE to files encoded in ASCII or Unicode escapes.
RMI tools enable remote communication between Java applications thus providing scope for development of distributed applications.
RMI enables an object running in one JVM to invoke methods on an object running in another JVM. These tools include:
Java Interface Definition Language (IDL) adds Common Object-Based Request Broker Architecture (CORBA) capability to the Java platform.
These tools enable distributed Java web applications to invoke operations on remote network services using industry standard Object Management Group (OMG) – IDL.
Likewise, we could use Internet InterORB Protocol (IIOP).
RMI-IIOP, i.e. RMI over IIOP enables programming of CORBA servers and applications via the RMI API. Thus enabling connection between two applications written in any CORBA-compliant language via Internet InterORB Protocol (IIOP).
These tools include:
These tools help in deploying Java applications and applets on the web. They include:
JDK provides us with htmlconverter. Furthermore, it’s used in conjunction with the Java Plug-in.
On the one hand, Java Plug-in establishes a connection between popular browsers and the Java platform. As a result of this connection, applets on the website can run within a browser.
On the other hand, htmlconverter is a utility for converting an HTML page containing applets to a format for Java Plug-in.
JDK brings javaws. We can use it in conjunction with the Java Web Start.
This tool allows us to download and launch Java applications with a single click from the browser. Hence, there is no need to run any installation process.
These are great tools that we can use to monitor JVM performance and resource consumption. Here are a few of these: :
These are experimental tools that we can leverage for troubleshooting tasks:
In this article, we identified that the basic difference between JVM, JRE, and JDK lies in their usage.
First, we described how the JVM is an abstract computing machine that actually executes the Java bytecode.
Then, we explained how to just run Java applications, we use the JRE.
And finally, we understood how to develop Java applications, we use the JDK.
We also took some time to dig into tools and fundamental concepts of this components.