What is Java virtual machine?
Java Virtual Machine (JVM) is a specification that provides runtime environment in which java bytecode can be executed. As the name implies, the JVM acts as a “virtual” machine or processor. Java's platform independence consists mostly of its Java Virtual Machine (JVM) . JVM makes this possible because it is aware of the specific instruction lengths and other particularities of the platform. The JVM performs following operation:
- Loads code
- Verifies code
- Executes code
In most cases, other programming languages, the compiler produce code for a particular Operating System but the Java compiler produce Bytecode only for a Java Virtual Machine . When you run a Java program, it runs as a thread within the JVM process. It is the JVM's responsibility to load your class files, verify code, interpret them and execute them. When you issue a command like java , the JVM loads the class definition for that particular class and calls the main method of that class.
It is the JVMs responsibility that makes it possible for the same class file to run on any other Operating Systems . The JVM takes your compiled platform-neutral byte code and interprets it to run platform-specific machine code. It can also compile it into native code with a JIT (a just-in-time compiler that compiles and caches your code, usually one method at a time). Thus, it is in the JVM where your code results, if needed, in native Operating System calls. Therefore, in the JVM , your platform-neutral threading code gets turned into platform-specific threading code.
Java allocates threads as needed for your application. The JVM manages the memory of your Java program. So, when you create an Object, or an Audio Clip, or a plain old float, Java allocates memory for both objects and primitives. Java determines when these items are no longer referenced, and, therefore, can have their memories reclaimed. The JVM, without any prompting from the user, runs the Garbage Collector thread (when possible or required) to reclaim used, unreferenced memory. In addition to interpreting bytecodes, the JVM must supply interfaces to the various subsystems managed by the Operating System for display, mouse, keyboard, file system and I/O ports etc.
Each Java application runs inside a runtime instance of some concrete implementation of the abstract specification of the Java virtual machine . There are three notions of JVM: specification, implementation, and instance.
- Specification : A document that describes what is required of JVM Implementation.
- Implementation: Known as JRE(Java Run Time Environment.)
- Instance: Whenever you will run a java class file an instance of JVM is created.
As shown in picture, JVM is divided into three main subsystems:
- Class Loader Subsystem
- Runtime Data Area
- Execution Engine
Class Loader Subsystem
The Java virtual machine has a flexible Class Loader architecture that allows a Java application to load classes in custom ways. In a JVM, each and every class is loaded by some instance of a java.lang.ClassLoader . A classloader is a special Java class file that is responsible for loading other classes onto a Java Virtual Machine. If a Java class is invoked and needs to be executed on a Java Virtual Machine, a special Java component, called a classloader , is used to find the Java class of interest, pull that Java class off of the file system, and execute the bytecode of that class file on the Java Virtual Machine.
Java Class Loader Subsystem loads, links and initializes the class file when it refers to a class for the first time at runtime. It is responsible for loading class files from file system, network or any other source. There are three default class loader used in Java, Bootstrap , Extension and System or Application class loader.
Boot Strap class Loader
When a JVM starts up, a special chunk of machine code runs that loads the system classloader. This machine code is known as the Bootstrap / Primordial classloader. It is platform specific machine instructions that kick off the whole classloading process. The bootstrap classloader also takes care of loading all of the code needed to support the basic Java Runtime Environment (JRE), including classes in the java.util and the java.lang packages .
The Extension class loader loads the classes from the JRE’s extension directories, such lib/ext directories. Extension ClassLoader delegates class loading request to its parent, Bootstrap and if unsuccessful, loads class form jre/lib/ext directory or any other directory pointed by java.ext.dirs system property. Extension ClassLoader in JVM is implemented by sun.misc.Launcher$ExtClassLoader .
System/Application Class Loader
System/Application Class Loader is responsible for loading Application Level Classpath, path mentioned Environment Variable etc.
Classloader - Linking
Linking is the process of incorporating the loaded bytecodes into the Java Runtime System so that the loaded Type can be used by the JVM. It involves verifying and preparing that class or interface, its direct superclass, its direct superinterfaces , and its element type (if it is an array type), if necessary.
- Verify: Bytecode verifier will verify whether the generated bytecode is proper or not if verification fails we will get verification error
- Prepare: For all static variables memory will be allocated and assigned with default values.
- Resolve: All symbolic memory references are replaced with the original references from Method Area.
This is the final phase of Class Loading, here all static variable will be assigned with the original values and static block will be executed.
Runtime Data Areas
The Java Virtual Machine (JVM) defines various run-time data areas that are used during execution of a program. Some of these data areas are created on Java Virtual Machine start-up and are destroyed only when the Java Virtual Machine exits. Other data areas are per thread . Per-thread data areas are created when a thread is created and destroyed when the thread exits.
It is memory which is shared among all Threads like Heap . It is created on Java Virtual Machine startup. It contains the code actually a compiled code, methods and its data and fields. Runtime constant pool is also a part of Method Area .
Heap is a memory place where the objects and its instance variable are stored. Each time an object is created in Java it goes into the area of memory known as heap.
Stack is a memory place where the methods and the local variables are stored. Variable references (either primitive or object references) are stored in the Stack
PC Register basically is a address of current instruction is being executed. Since each thread some sets of method which is going to be executed depends upon PC Register . It has some value for each instruction and undefined for native methods . It is usually for keep tracking of instructions.
Native Method Stack
Native methods are those which are written in languages other than java. JVM implementations cannot load native methods and can't rely on conventional stacks . It is also associated with each thread. In short it same as stack but it is used for native methods .
This is the core of the JVM. Execution engine can communicate with various memory areas of JVM. Each thread of a running Java application is a distinct instance of the virtual machine's execution engine. The byte code that is assigned to the runtime data areas in the JVM via class loader is executed by the execution engine.
- JIT Compiler
- Garbage Collector
Reads, interprets and executes the bytecode instructions one by one. As it interprets and executes instructions one by one, it can quickly interpret one bytecode, but slowly executes the interpreted result. This is the disadvantage of the interpret language. The 'language' called Bytecode basically runs like an interpreter .
The JIT compiler converts the bytecode to an intermediate-level expression, IR (Intermediate Representation), to execute optimization , and then converts the expression to native code. The JIT compiler has been introduced to compensate for the disadvantages of the interpreter. The main purpose of JIT compiler is to improve the performance. Internally JIT compiler maintains a separate count for every method. Whenever JVM across any method call, first that method will be interpreted normally by the interpreter and JIT compiler increments the corresponding count variable.
Garbage collection (GC) is the process that aims to free up occupied memory that is no longer referenced by any reachable Java object, and is an essential part of the Java virtual machine's (JVM's) dynamic memory management system. All Java objects automatically grab the memory that they need when they are created, and when the object is no longer need, the Java Garbage Collection process reclaim the memory. That means, the Garbage Collector tracked live objects and everything else designated garbage. More about.... Java Garbage Collection Basics
Native Method Interface
Native methods allow you to use code from other languages such as C or C++ in your java code. You use them when java doesn't provide the functionality that you need.
Native Method Libraries
Native Method Libraries are Collection of the Native Libraries which is required for the Execution Engine .