Java Virtual Machine (JVM)

JVM

  • Introduction to JVM
  • Overall structure of JVM
  • JVM runtime data area
    • program counter
    • Java virtual machine stack
    • native method stack
    • heap
    • method area
  • Class loading mechanism
    • 1. Loading
    • 2. Verification
    • 3. Preparation
    • 4. Resolution
    • 5. Initialization
    • class loader
      • Bootstrap ClassLoader
      • Extension ClassLoader:
      • Application ClassLoader:
    • Parent delegation mechanism

Introduction to JVM

JVM (Java Virtual Machine) means Java virtual machine, which is a virtual computer or runtime environment that runs Java programs on a computer. It acts as an intermediate layer between Java applications and computer hardware, is responsible for interpreting and executing Java source code, and provides cross-platform capabilities for Java applications, so that the same Java program can run on different operating systems without Rewrite or modify the source code.

JVM overall structure

Class loader: Load class files.
Runtime data area: includes program counter, Java virtual machine stack, local method stack, heap, and method area.
Execution engine: Execute bytecode or local methods.

JVM runtime data area

During the execution of a Java program, the Java virtual machine divides the memory it manages into several different data areas. These areas have their own purposes, as well as the time of creation and destruction. Some areas always exist with the start of the virtual machine process, and some areas are created and destroyed depending on the start and end of the user thread. According to the “Java Virtual Machine Specification”, the memory managed by the Java virtual machine will include the following runtime data areas:

Program Counter

  • Function: Used to record the bytecode instruction address executed by the current thread.
  • Features: The program counter is thread-private, and each thread has a program counter. It is used in multi-threaded environments to guide thread execution, such as jumping to the location of the next instruction.
  • Garbage collection: The program counter does not involve memory allocation, so garbage collection is not required.

Java virtual machine stack

  • Function: Used to store local variables, operand stacks, method exits, etc. for method calls.
  • Features: Each thread has its own stack, which is used to store local variables and status information of method calls. The stack is private to the thread. When a method is called, a new stack frame is pushed onto the stack. When the method returns, the stack frame is popped.
  • Garbage collection: The data on the stack is private to the thread and does not require garbage collection.

Local method stack

  • Function: Used to execute Native Method.
  • Features: The local method stack is similar to the stack, but it serves local methods. Local methods are methods written in non-Java languages and are usually called by JNI (Java Native Interface).
  • Garbage collection: Like the stack, the data on the local method stack is also private to the thread and does not require garbage collection.

Heap

  • Function: Used to store Java object instances.
  • Features: The heap is a large memory pool that can dynamically allocate and release memory space. It is the most commonly used memory area in Java and is used to store instance objects, including the object’s member variables and instance methods.
  • Garbage collection: When objects in the heap memory are no longer referenced, they will be automatically reclaimed and released by the garbage collection mechanism.

Method area

  • Function: Used to store class information, static variables, constant pool and other data.
  • Features: The method area contains the structural information of the class, such as field and method information, and the constant pool, which stores literal constants and symbol references in the class. It is an area shared by various threads.
  • Garbage collection: The JVM specification does not explicitly require that the method area must be garbage collected, but some JVM implementations may perform garbage collection operations in the method area.

Class loading mechanism

In the Java virtual machine, the class loading process is divided into the following stages, each stage is responsible for different tasks:

1. Loading

  • Get the binary byte stream that defines a class by its fully qualified name
  • Convert the static storage structure represented by this byte stream into a runtime data structure in the method area
  • Generate a java.langClass object representing this class in the memory, which serves as the access point for various data of this class in the method area.

2. Verification

  • The purpose is to ensure that the information contained in the byte stream of the class file meets the current virtual machine requirements, ensures the correctness of the loaded class, and does not endanger the security of the virtual machine itself.
  • It mainly includes four types of verification, File format verification, Metadata verification, Bytecode verification, Symbol reference verification .

3. Preparation

  • Allocate memory for the class variable and set the default initial value of the class variable, which is zero.
  • This does not include static modified with final, because final will be allocated during compilation and will be explicitly initialized in the preparation phase;
  • The instance variable will not be initialized here. The class variable will be allocated in the method area, and the instance variable will be allocated to the Java heap along with the object.

4. Resolution

  • The process of converting symbol references in the constant pool into direct references.
  • In fact, parsing operations are often performed after the JVM has completed initialization.
  • A symbolic reference is a set of symbols that describes the referenced target. The literal form of symbol references is clearly defined in the class file format of the “Java Virtual Machine Specification”. A direct reference is a pointer directly pointing to the target, a relative offset, or a handle that indirectly locates the target.
  • Parsing actions mainly target classes or interfaces, fields, class methods, interface methods, method types, etc. Corresponds to CONSTANT_Class_info, CONSTANT_Fieldref_info, CONSTANT_Methodref_info, etc. in the constant pool

5. Initialization

  • The initialization phase is the process of executing the class constructor method ().
  • This method does not need to be defined. The javac compiler automatically collects the assignment actions of all class variables in the class and merges them with the statements in the static code block.
  • Instructions in the constructor method are executed in the order in which the statements appear in the source file.
  • () is different from the constructor of a class.
  • If the class has a parent class, the JVM will ensure that the parent class’s () has been executed before the subclass’s () is executed.
  • The virtual machine must ensure that the () method of a class is locked synchronously under multiple threads.

Class loader

Bootstrap ClassLoader

  • This class loader is implemented by the JVM itself. It is not a Java class and cannot be accessed directly.
  • It is used to load Java’s core library (JAVA HOME/jre/ lib/rt.jar, resources.jar or sun.boot.class.path code> path), used to provide classes needed by the JVM itself.
  • Does not inherit from java.lang.ClassLoader and has no parent loader.
  • Load extension classes and application class loaders and specify them as their parent class loader.
  • For security reasons, the Bootstrap startup class loader only loads packages whose names begin with java, javax, sun, etc. the type.
 ClassLoader bootstrapClassLoader = String.class.getClassLoader();
        System.out.println(bootstrapClassLoader);// null

Extension ClassLoader:

  • Written in Java language, implemented by sun.misc.Launcher$ExtClassLoader.
  • Derived from the ClassLoader class.
  • The parent class loader is the startup class loader.
  • Load the class library from the directory specified by the java.ext.dirs system property, or from the jre/lib/ext subdirectory (extension directory) of the JDK installation directory Load class library. If a user-created JAR is placed in this directory, it will also be automatically loaded by the extension class loader.
 ClassLoader extClassLoader = SunEC.class.getClassLoader();
        System.out.println(extClassLoader);// sun.misc.Launcher$ExtClassLoader@53d8d10a

Application ClassLoader:

  • Written in java language and implemented by sun.misc.Launcher$AppClassLoader.
  • Derived from the ClassLoader class.
  • The parent class loader is the extension class loader.
  • It is responsible for loading the class library under the path specified by the environment variable classpath or the system property java.class.path.
  • This class loader is the default class loader in the program. Generally speaking, Java application classes are loaded by it.
  • The class loader can be obtained through the ClassLoader#getsystemclassLoader() method
 ClassLoader appClassLoader = App.class.getClassLoader();
        System.out.println(appClassLoader);// sun.misc.Launcher$AppClassLoader@18b4aac2

Parent delegation mechanism

Class loading is completed through the parent delegation model. The parent delegation model is the hierarchical relationship between class loaders as shown in the figure below.


How it works:

  • If a class loader receives a class loading request, it will not load it first, but will delegate the request to the parent class loader for execution.
  • If the parent class loader still has its parent class loader, it will be further delegated upward, recursively, and the request will eventually reach the top-level startup class loader.
  • If the parent class loader can complete the class loading task, it will return successfully. If the parent class loader cannot complete the loading task, the child loader will try to load it by itself. This is the parent delegation mode.

Advantages:

  • Avoid repeated loading of classes.
  • To protect program security, using the parent delegation model can also ensure that Java’s core API is not tampered with.