blog;

Java Virtual Machine.

What is the JVM?

Java Virtual Machine.

Originally posted on Fri Sep 17 2021

The Java Virtual Machine (JVM) is a program that executes other programs.


What is it used for?

The JVM has two main functions:

  1. Allow Java programs to run on any device or operating system (Write Once, Run Anywhere).
  2. Manage and optimise program memory

Before the introduction of Java and the JVM, software developers had to write code specific to an operating system and manage program memory themselves.

JVM
JVM

The JVM provides a runtime environment for Java code. We can configure the JVM's settings before running, which allows us to set certain constraints and then we rely on it to manage resources during execution.


Resource Management in the JVM

The JVM handles memory allocation and therefore one of the most common interactions with the JVM is to check memory usage. As memory allocation is happening automatically and dynamically in the JVM, it uses a process called Garbage Collection to manage the memory. GC identifies unused memory and clears it. Originally this process wasn't very quick, so over the years many algorithms have been developed to handle GC.

The memory comes from the heap. The heap is where the objects of a Java program live.


Java bytecodes

Java programs are compiled into Java bytecodes. The JVM then executes these bytecodes, so they can be seen as the machine language of the JVM. The Java Compiler reads Java language .java files and turns them into bytecodes in .class files.

The Java stack is used to store parameters for and results of bytecode instructions, to pass parameters to and return values from methods, and to keep the state of each method invocation.


JVM Components

JVM consists of three main components or subsystems:

  • Class Loader Subsystem is responsible for loading, linking and initializing a Java class file otherwise known as dynamic class loading.
  • Runtime Data Areas contain method areas, PC registers, heap, stack areas and threads.
  • Execution Engine contains an interpreter, compiler and garbage collection area.

Lots of new terms in there, so let me try to explain them!

JVM Architecture
JVM Architecture

Class Loader

The class loader loads class files! Makes sense right. it is responsible for loading, linking and initialising Java class files.

  1. Loading: The Class loader reads the .class file, and generates the corresponding binary data then saves it in the method area.
  2. Linking: Performs verification (ensure the .class file is correct), preparation (allocates memory), and (optionally) resolution (replace symbolic references with direct references).
  3. Initialisation: All static variables are assigned with their values defined in the code and static block (if any). This is executed from top to bottom in a class and from parent to child in the class hierarchy.

Method Area

Stores things like class metadata, variable information, and code for methods. There is one method area per JVM.

Heap

All the Objects, instance variables and arrays. Memory on the heap is shared across all threads, so again one per JVM.

JVM Language Stacks

Java language stacks store local variables, and partial results. Each thread has its own JVM stack, created at the same time the thread is created. A new frame in the stack is created whenever a method is invoked, and it is deleted when method invocation process is complete.

PC Registers

The PC register stores the address of the JVM instruction which is currently executing. Each thread has its separate PC register.

Native Method Stacks

Native methods are used to move native code written in other languages into a Java application.

Execution Engine

The execution engine is the central component of the JVM. It communicates with various memory areas of the JVM. Each thread of a running application is a distinct instance of the virtual machine’s execution engine. The Execution Engine itself contains 3 main components:

  1. Interpreter: It reads the byte code and converts into the machine code and executes them in a sequential manner. The problem with the interpreter is that it interprets every time, even the same method multiple times, which reduces the performance of the system. To overcome this problem JIT Compilers were introduced.
  2. JIT Compiler: JIT compiler counterbalances the interpreter’s disadvantage of slow execution and improves the performance.
  • At run time, the JIT compiler converts the bytecode into machine code. The JIT compiler is activated when a method is called. If the method has already been compiled to machine code, that is called rather than re-interpreting the code.
  • This does sacrifice start up time for application performance.
  • Profiler: This is a tool which is the part of JIT Compiler is responsible to monitor the java bytecode constructs and operations at the JVM level.
  1. Garbage Collector: Already mentioned above.

Native Method Interface and Libraries

Allows Java code which is running in a JVM to call libraries and native applications written in other languages.

Reference: https://www.geeksforgeeks.org/jvm-works-jvm-architecture/

So there it is, the JVM basically allows you to run Java code anywhere, and tries it's best to do it efficiently!


Me

Post by

Josh Glasson

Software Developer. Creator and owner of this blog.