JVM
If you work with java you know the JVM. But do you know how it works? Let's see an overview of what happens behind the scenes.
Summary
What is JVM
The Virtual Machine has the idea to implements a physical machine, and Java use that to make possible execute the programs in any platform (WORA - Write Once Run Anywhere).
Java Virtual Machine can be defined such an environment where you can execute your Java application in any platform. It provides, for example, dynamic memory management, garbage collector, Threads, IO and native operations. The main tasks in the JVM are loading code, verifying code, executing code and provide a runtime environment.
The JRE (Java Runtime Environment) is the JVM's implementation. The JDK is a software development environment to implement java applet and apps. It includes, for example, JRE (loader/interpreter), a compiler (javac), a document generator (Javadoc) and an archiver (jar).
Left: JDK vs JRE vs JVM / Right: summary of the process.
More detail about the differences between JVM, JRE and JDK you can see here.
JVM Subsystems
ClassLoader
It is responsible for loading, linking (verify [bytecode], prepare [memory allocation to static variables], resolve [references]) and initialization (static variables and blocks) the class files when it is referred by other class at runtime.
Runtime Data Areas
It is composed by Method Area (class level data - static blocks/static variables/references), Heap Area (objects, instances and arrays), Stack Area (a new stack is created for each new thread; local variables are created in the stack; one stack frame is created for every method call), PC Registers (a new register is created for each thread to hold address's instructions), Native Method Stacks (native methods informations - by each thread).
Execution Engine
It reads and executes the bytecode assigned from the Runtime Data Area piece by piece. Interpreter (interpreter [fast] and execute[slowly] the bytecode), JIT Compiler (it is used to repeated code which compiles entire bytecode and changes it to native code, used directly for repeated method calls - it is responsible for the optimization of the Java programs ), Garbage Collector (collects and removes unreferenced objects).
Java Native Interface (JNI)
It is like an interface between the Java code and the native (C/C++). It provides the native libraries required for the Execution Engine.
Native Method Libraries
Collection of Native libraries (related to the platform) and native methods implementation used by Execution Engine.
JVM Architecture Diagram
Heap Memory
The heap memory is where are allocated instances. Until Java 7 the memory is divided into generations based on the age of the objects. The Young generation is the part of memory where are the small objects and which are collected frequently. The Old Generation has a larger object and promoted from the Young part. The Permanent Generation (PermGen), store class-level information (fields, methods, runtime constant pool, internalized Strings, etc). The data is rarely collected. Before Java 7 the interned Strings were stored in the PermGen.
The JVM is responsible for memory management, allocating and de-allocating memory. This management is performed by the Garbage Collector (GC) which verify if the objects are referenced or not. If the object is used it must be kept in the heap. The rest of the objects will be removed and the heap space will be reorganized to have the alive objects together in a continuous position.
From post: Understanding JVM Memory management
Since Java 8 the PermGen does not exist anymore and it has been replaced by the Metaspace which not contiguous in heap. Now the metadata was moved to the native memory and it makes possible to be free of the PermGen exception (no more java.lang.OutOfMemoryError). You can control the limit using MaxMetaspaceSize.
After that, Java already delivery two new garbage collectors (ZGC and Shenandoah - stable in JDK17) that manage the memory in a different way. Both are concurrent with the application and use only one generation.
From VOXXEDDAYS19: Concurrent Garbage Collectors: ZGC & Shenandoah by Simone Bordet
More detail about JVM memory management you can see here. If you want to know about options to configure JVM you can see in these other posts: [1], [2], [3]. More about GC algorithms you can see here.
GraalVM
It is a new option of VM that offer a new version of the JIT. The GraalVM is considered a polyglot VM because now you can run applications written not only in Java but JavaScript, Python, Ruby and many others. Also, it allows interoperability in a shared runtime, the licences are Community Edition (CE) and Enterprise Edition (EE) and the components are Graal (JIT), Graal Polyglot APIs, Graal SDK and JVM.
Graal Features:
- Run your code faster and more efficiently
- Interoperate directly with most modern programming languages
- Embed languages with the Graal SDK
- Create compiled native images
- Use a single set of tools to monitor, debug, and profile all your code
Related Posts
- Java 8 - Part VII [Collections]
- Java 8 – Part VI [File IO NIO.2]
- Java 8 – Part V [Concurreny]
- Java 8 – Part IV [Streams]
- Java 8 – Parte III [Lambda]
- Java 8 - Part II [Localization, Date, Time]
- Java 8 - Language Enhancements
- JVM
References
- The JVM Architecture Explained
- How JVM works
- Difference Between JDK Vs. JRE Vs. JVM
- Difference Between JVM, JRE and JDK
- Understanding JVM Memory Management
- Java Virtual Machine (JVM) Stack Area
- Conhecendo o Graal - o novo compilador JIT do Java
- Onde foi parar o PermGen do Java?
- Plumbr - Garbage Collection Handbook