How Does the Java Virtual Machine Work?
First, the code is compiled and converted into bytecode.
- This bytecode is interpreted on different machines. Between the host system and Java source, bytecode is an intermediate language.
- In JVM, Java is responsible for allocating memory space.
- JVM performs different tasks like it loads the code, verifies it, executes the code, and provides a runtime environment.
- It provides definitions for the memory area, class file format, register set, garbage collector heap, fatal error reporting, etc.
JVM Architecture
Java Architecture is internally basically divided into seven segments. It contains a classloader, memory area, execution, etc.
1. Classloader
It's a subsystem of JVM used to load class files. When we execute the code, it's loaded by the classloader. There are built-in classloaders in Java.
- Bootstrap ClassLoader: This is the first classloader, the superclass of the Extension classloader. It loads the rt.jar file, which contains all files of Java Standard Edition like Java.lang package classes, java.net package classes.
2. Extension ClassLoader: This is the child classloader of Bootstrap and parent classloader of System classloader.
3. System/Application Classloader: It loads the class files from classpath. It is also known as the Application classloader.
2. Class(Method)Area
Class (Method)Area stores per-class structures such as the constant runtime pool, field and method data, and the form code.
3. Heap:
It is the runtime method where objects are allocated.
4. Stack:
It stores frames and holds local variables and partial results and plays a part in method invocation and return.
5. Program Counter Register:
This register contains the address of the Java Virtual machine instruction, which is currently being executed.
6. Native Method Stack:
It has all the native methods applicable in the application.
7. Execution Engine:
This consists of three parts:
- A virtual processor:
- Interpreter:
- Just-In-Time(JIT) compiler:
8. Java Native Interface:
It is a framework that facilitates an interface to communicate with another application coded in other languages like C++, C, Assembly, etc. Java uses this framework to send output to the console to interact with OS libraries.
You can also check about Java Tokens and Hashcode Method in Java here.
JVM Memory :
The Java Virtual Machine (JVM) is the revolutionary tool of Java's platform-independent capabilities, that executes Java bytecode in a manner that allows the same code to run on any machine that has a compatible JVM. Memory management in JVM is crucial for optimizing application performance and avoiding common issues like memory leaks and garbage collection pauses. Let's the JVM memory in detail, like what comes under this :
- Heap Memory
The heap memory is used for allocating memory to objects and JRE classes. It is divided into two main parts: the Young Generation and the Old Generation. The Young Generation is further divided into the Eden Space, where new objects are allocated, and the Survivor Spaces (S0 and S1), which are used during minor garbage collection. The Old Generation, also known as the Tenured Space, is where long-surviving objects are stored. The garbage collector (GC) is responsible for managing the heap memory and automatically freeing up memory that is no longer being used by the application. - Non-Heap Memory
Non-heap memory is used to store per-class structures, method data, and memory required by JVM internal processing. It is divided into several areas, including the Permanent Generation (PermGen) (deprecated since Java 8), Metaspace (Java 8+), and Code Cache. PermGen was used to store class structures, method data, and interned Strings, but it has been replaced by Metaspace in Java 8 and later versions. Metaspace stores class metadata and memory required by JVM internal processing. The Code Cache is used to store compiled native code generated by the JIT (Just-In-Time) compiler. Unlike heap memory, non-heap memory is not managed by the garbage collector. - Stack Memory
Stack memory is used for storing local variables, method calls, and partial results. Each thread in the application has its own stack. Stack memory is allocated on a per-method basis and is automatically deallocated when the method returns. If the stack memory is exhausted, a `StackOverflowError` is thrown. Stack memory is generally much smaller than heap memory, and its size can be configured using the `-Xss` JVM option. - Native Memory
Native memory is the memory required by native libraries (e.g., C or C++) used in the application. This memory is managed by the operating system, not the JVM. Native memory usage can be significant in applications that heavily rely on native libraries, and it is important to monitor and manage this memory to avoid issues like memory leaks or excessive memory consumption.
Features of the JVM?
The Java Virtual Machine (JVM) is a crucial component of the Java Runtime Environment (JRE) that enables Java applications to run on any device or operating system. Key features of the JVM include:
- Platform Independence: The JVM abstracts the underlying hardware and operating system, allowing Java programs to be written once and run anywhere without modification.
- Automatic Memory Management: The JVM handles memory allocation and garbage collection automatically, reducing the risk of memory leaks and simplifying the developer's task.
- Security: The JVM includes a security manager that enforces access controls, protecting the system from untrusted code execution and ensuring a secure runtime environment.
- Performance Optimization: Through Just-In-Time (JIT) compilation, the JVM converts bytecode into native machine code at runtime, enhancing execution speed and performance.
- Multithreading: The JVM supports concurrent execution of multiple threads, enabling efficient use of CPU resources and improving application performance.
- Exception Handling: The JVM provides a robust exception handling mechanism, allowing programs to manage errors gracefully and maintain stable operation.
- Class Loader: The JVM dynamically loads classes at runtime, facilitating modularity and dynamic application updates.
These features collectively make the JVM a powerful and versatile platform for running Java applications.
Frequently Asked Questions
What does JVM do in Java?
The Java Virtual Machine (JVM) executes Java bytecode, enabling platform-independent execution of Java applications. It manages memory, handles exceptions, supports multithreading, and optimizes performance through Just-In-Time (JIT) compilation, ensuring efficient and secure runtime environments for Java programs.
What is JVM vs JRE in Java?
The Java Virtual Machine (JVM) is the runtime engine that executes Java bytecode. The Java Runtime Environment (JRE) includes the JVM along with libraries and other components necessary for running Java applications, but without development tools.
Is JVM present in JRE or JDK?
The JVM is present in both JRE (Java Runtime Environment) and JDK (Java Development Kit). JRE includes only the runtime environment needed for running Java applications, while JDK includes the JRE plus development tools such as compilers and debuggers.
What are the responsibilities of JVM?
The JVM has two primary functions: to allow Java programs to run on any device or operating system (known as the "Write once, run anywhere" principle) and to manage and optimize program memory.
Conclusion
In this article, we learned about the Java Virtual Machine (JVM) and its architecture, which plays a pivotal role in Java's platform-independent capabilities. We looked into JVM memory management, which explained its structured components like Heap Memory, Stack Memory, and Code Cache. These features and their functions help us understand how the JVM executes Java bytecode efficiently, which ensures seamless application performance across various computing platforms.
Related article:
Difference between JDK, JRE and JVM
Java Ioexception
Addressing Modes of 8086
Why is Java Platform Independent
Data Warehouse Architecture