Understanding the JVM Architecture
The Java Virtual Machine (JVM) is a virtual machine that provides an environment to execute compiled Java code (also called byte code). The implementations of JVM vary depending on the operating system it is meant for. This article presents an overview of JVM and its components.
Inside the Java Virtual Machine (JVM)
The JVM is responsible for the following:
- Loading, verifying, and executing the byte code
- Providing a runtime environment for execution of byte code
- Memory management and garbage collection
The major components of the JVM include:
Constant Pool: The constant pool is a pool of constants. In other words, it contains a list of all the constants contained in a class. Note that each class has its own constant pool in memory. The constants are literals that don't change over time.
Class Loader: This is responsible for loading the class files or byte code files. The class loader is responsible for loading classes and interfaces residing in the byte code. The three basic functions of the class loader include:
- Loading byte code
- Linking (verification, memory allocation for byte code, and resolution or transformation of symbolic references to direct references)
- Initialization of variables to their default values
Heap Area: This is the region of memory where objects are stored. Note that if the size of an object cannot be determined at compilation time, such objects are stored in the heap; in other words, instances of classes. On the contrary, if the compiler can determine the size of an object at compilation time, such objects are placed in the stack in memory. An example would be variables belonging to fundamental data types.
The heap area also contains the Garbage Collected Heap. The garbage collected heap is an area of the memory within the context of the JVM where objects are stored. It de-allocates the memory occupied by these objects as and when they are no longer needed or referenced in the code. The GC works on the basis of two principles: reference counting and mark and sweep. Note that local object references reside in the stack whereas the actual objects are stored in the heap. The GC works in the background and releases memory when objects are no longer in use.
Stack Area: The JVM stores local variables and intermediate results of execution of methods in the stack. Note that each thread inside the JVM contains its own private stack. Also, each method contains its own method frame: The frame is created at the time the method is called and is deleted when the execution of the method is over.
Register Area: This contains the registers used by the JVM. The JVM contains four registers: pc, optop, frame, and vars. Here is what these registers are used for:
- pc: This is the program counter or the register that points to the address of the currently executing instruction.
- optop: This is the register that contains the address of the top of the operand stack.
- frame: This register points to the execution environment of the currently executing method.
- vars: This register points to the first local variable in the currently executing method.
Execution Engine: This is responsible for execution of the compiled code or byte code. The execution engine comprises of the following:
- Just in Time Compiler (JIT): The JIT compiles the byte code to machine language instructions at run time,
- Virtual Processor: The virtual processor is responsible for processing the operation codes and executing them sequentially.
- Interpreter: The interpreter is responsible for reading the stream of byte code, interpreting the instructions, and then executing them through the virtual processor.
Here's a list of some references to further study on this topic.
The Java Virtual Machine (JVM) is a virtual machine that analyzes and executes Java byte code instructions. In this article, we explored the Java Virtual Machine (JVM) and its components. Happy reading!