Overview of class loading mechanisms

Vm Class loading mechanism: The Java VM loads the data describing the Class from the Class file to the memory, verifies, converts, and initializes the data, and finally forms Java types that can be directly used by VMS.

The process of class loading consists of seven stages: loading, verification, preparation, parsing, initialization, use and unloading. The order of the five stages of load, verification, preparation, initialization and uninstallation is determined and must be started step by step. Although the five stages need to be started, they are not required to be completed, and the next stage may start while the previous one is still unfinished.

The timing of class loading

There are no specific requirements for when the virtual machine will perform the first phase of class loading, leaving it up to the implementation of the virtual machine, but there are only six cases in which the type (class or interface) must be initialized immediately (loading, validating, and preparing the class must be done before then, of course) :

  1. When the bytecode instructions new, getStatic, putstatic, and Invokestatic are encountered, the initialization phase must be triggered first if the type is not initialized. Typical Java code scenarios that can generate these four instructions include:
    • Instantiate the object using the new keyword
    • Reads or sets a static field of a type (except static fields modified by final that have been pooled at compile time)
    • Calls a static method of a type
  2. When you emit calls to a method type using the java.lang.Reflect package, if the type is not already initialized, you need to initialize it first.
  3. When initializing a class, if its parent class has not been initialized before, the initialization of its parent class must be triggered first. However, when an interface is initialized, its parent interface is not required to be fully initialized. It is initialized only when the parent interface is actually used (such as referencing constants defined in the interface).
  4. However, when the VM starts, a primary class must be specified. The VM initializes this primary class first.
  5. When using the new dynamic language support in JDK 7, If a Java lang. Invoke. The final analytical results for MethodHandle instance REF_getStatic, REF_putStatic, REF_invokeStatic, REF_newInvokeSpecial handle four kinds of methods, If the class corresponding to the method handle is not initialized, the initialization of the class must be triggered first.
  6. When an interface implements the default methods of JDK 8, the implementation class of the interface needs to be initialized before it.

The six scenarios above that trigger type initialization are called active references to a type, and the rest are called passive references.

class Dfather {
    static int count = 1;
    static{
        System.out.println("Initialize class Dfather"); }}class Dson extends Dfather{
    static{
        System.out.println("Initialize class Dson"); }}public class NotInitliazion {
    public static void main(String[] args) {
        // Passive reference scenario 1: subclass Dson does not trigger initialization
        System.out.println(Dson.count);
        // Passive reference scenario 2: Dfather initialization is not triggered
        Dfather[] nums = new Dfather[10]; }}Copy the code

The process of class loading

loading

During the load phase, the virtual machine needs to do the following three things:

  1. Get the binary byte stream that defines this Class by the fully qualified name of a Class (not from a Class file, but from other sources such as networks, dynamic generation, databases, etc.);
  2. Convert the static storage structure represented by this byte stream to the runtime data structure of the method area;
  3. Generate a java.lang.Class object representing the Class in memory (or in the case of the HotSpot virtual machine, the method area), which acts as a data access point for the Class.

Compared to other phases of class loading, the loading phase (specifically, the action of the loading phase to retrieve the binary byte stream of the class) is the most controllable, because developers can either use the system-provided class loader to complete the loading, or they can customize their own.

Stages of loading and the connection part of the content, such as part of the bytecode file format validation action) was performed by cross loading phase is not yet complete, may have begun connection phase, but those caught in the clip in the middle of the stage of action, still belongs to the content of connection phase, the two stages of start time remains fixed order.

check

Validation is the first step in the connection phase, where the purpose is to ensure that the byte stream of the Class file contains information that meets the requirements of the current virtual machine and does not end with the security of the virtual machine itself. The verification phase will roughly complete the inspection actions of the qualification phase:

  • File format validation: Verifies that the byte stream complies with the Class file format specification (for example, if the byte stream starts with the magic number 0xCAFEBABE, if the primary and secondary versions are within the scope of the current VIRTUAL machine, if there are unsupported types in the constant pool)
  • Metadata validation: Semantic analysis of the information described by bytecode to ensure that the information described conforms to the Requirements of the Java language specification (e.g., does this class have a parent other than java.lang.object)
  • Bytecode verification: through data flow and control flow analysis, to determine that the program semantics are legal and logical;
  • Symbolic reference validation: Ensures that the parse action is performed correctly when a symbolic reference is converted to a direct reference.The validation phase is important, but not required, and has no effect on the program runtime.If the referenced class is repeatedly validated, consider using the -xVerifyNone parameter to turn off most of the class validation to shorten the virtual machine class load time.

To prepare

The preparation phase is the formal allocation of memory for Class variables (static member variables) and the setting of their initial values (zero). The memory used by these variables will be allocated in the method area (JDK 7 and later, Class variables will be allocated in the Java heap along with Class objects). Only class variables are allocated, not instance variables, which are allocated in the heap along with the object when it is instantiated.

The initial value in the preparation phase is usually zero for the data type, assuming that a class variable is defined as:

public static int value = 123;
Copy the code

So, the value of the variable after the preparation phase is 0 instead of 123. Since we have not yet started executing any Java methods at this point and the putStatic instruction that copies value to 123 is mutated and stored in the class constructor method (), assigning value to 123 will only be performed during initialization. The “special case” is that a class field whose field attribute is ConstantValue is initialized to the specified value during the preparation phase, so after marking final, value is initialized to 123 instead of 0 during the preparation phase.

public static final int value = 123;
Copy the code

parsing

The process by which the Java virtual machine replaces symbolic references in a constant pool with direct references. A symbolic reference is a set of symbols that describe a target, which can be any literal. A direct reference is a pointer to a target directly, a relative offset, or a handle to the target indirectly.

The parse action is mainly for class or interface, field, class method, interface method, method type, method handle, and call qualifier class symbol references.

Initialize the

In the preparation phase, the variable has been assigned an initial value (zero) required by the system; It is during the initialization phase that the Java virtual machine actually starts executing the Java program code written in the class. More directly, the initialization phase is the process of executing the class constructor < Clinit >() method.

< clinit > () by the compiler automatically collect all kinds of variable assignment in class action and static block static {} the statement in merger, the compiler’s collection of order by the order of the statement in the source file is determined by, static blocks can only access to the definition in the static block variables before and after its variables, The previous static block can be assigned, but not accessed.

Unlike class constructors, the

() method does not require an explicit call to the parent class constructor, and the virtual machine ensures that the

() method of the parent class is executed before the

() method of the subclass is executed.


Unlike a class, the

() method that executes an interface does not need to execute the

() method of the parent interface first, because the parent interface is initialized only when a variable defined in the parent interface is used.

The

() method is not required for a class or interface, and the compiler may not generate the

() method for the class if there are no static blocks and no assignments to class variables.

This is an initialization of the class, not an instance of the class, so the constructor of the class is not called here.

Attached: class instance (class object) creation process, these must not know the JVM knowledge, I use the mind map sorted out

Class loader

The code that performs the class-loading action of “getting a binary stream describing a class by its fully qualified name” is called a classloader.

Comparing two classes (equals(), isAassinableFrom(), isInstance(), and the instanceof keyword) for equality in A Java program only makes sense if both classes are loaded by the same classloader; Otherwise, even if two classes come from the same Class file and are loaded by the same Java virtual machine, but they are loaded by different classloaders, the two classes must not be equal.

Class loader classification

  • Bootstrap classLoader:c++Write, loadjavaCore libraryjava.*,ExtClassLoaderandAppClassLoader. Since bootstrap classloaders involve the details of the virtual machine’s local implementation, the developer cannot get a reference to the bootstrap classloader directly, so direct operations are not allowed.
  • ExtClassLoader:javaWrite, load extension libraries, such asclasspathIn thejrejavax.*orjava.ext.dirSpecify a class in a location where developers can use the standard extension classloader directly.
  • AppClassLoader: The directory in which the loader is written in Java, such asuser.dirThe class of the location.
  • CustomClassLoader: Java, user-defined class loader, can load the specified pathclassFile.

Parent delegation mechanism

How it works: When a classloader receives a classloading request, the classloader first delegates the request to the parent classloader. This is true of every class loader, and the subclass loader will only attempt to load it itself if the parent class loader cannot find the specified class in its search scope.

What the parental delegation model does:

Avoid reloading: Java classes have a hierarchy of priorities with their classloaders to avoid reloading classes when the parent has already loaded the class, so there is no need for the child ClassLoader to load the class again.

Avoid core class tampering: The types defined in the Java core API will not be arbitrarily replaced, but are loaded by starting the class load, ensuring that the core API classes are the same class. Suppose a class named java.lang.Integer is passed over the network and passed to the launcher class loader in parental delegate mode, and the launcher class loader finds the class with that name in the core Java API, finds that it has been loaded, and does not reload the java.lang.Integer passed over the network. Instead, return the loaded integer.class directly, which prevents the core API library from being tampered with.