Class loading process:

The timing of class loading

The Java Virtual Machine Specification does not enforce the conditions under which to begin the first phase of the classloading process, “loading,” and leaves this up to the implementation of the virtual machine. But for the initialization phase, the Java Virtual Machine Specification specifies that there are only six cases in which classes must be “initialized” immediately (and loading, validation, and preparation naturally need to begin before that) :

  1. When you encounter four bytecode instructions — New, getstatic, putstatic, or Invokestatic — if the type has not been initialized, you need to trigger its initialization phase first. Typical Java code scenarios that can generate these four instructions are:

    • When an object is instantiated using the new keyword.
    • Read or set a static field of a type (except for static fields that are modified by final and have been put into the constant pool at compile time).
    • When a static method of a type is called.
  2. When a reflection call is made to a type using the java.lang.Reflect package’s methods, initialization needs to be triggered if the type has not already been initialized. 3) When initializing a class, if the parent class has not been initialized, the initialization of the parent class needs to be triggered first.

  3. When the virtual machine starts, the user needs to specify a primary class (the one containing the main() method) to execute, and the virtual machine initializes this primary class first.

  4. 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 has not been initialized, it needs to be initialized first.

  5. When an interface defines a new JDK 8 default method (an interface method decorated with the default keyword), if any of the interface’s implementation classes are initialized, the interface should be initialized before it.

The process of class loading

loading

The “Loading” stage is a part of the whole “Class Loading” process, and I hope you didn’t confuse these two similar-looking terms. During the load phase, the Java virtual machine needs to do three things: 1) get the binary byte stream that defines a class by its fully qualified name. 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 as an access point to the various data of the Class in the method area.

validation

Validation is the first step in the connection phase. The purpose of this phase is to ensure that the information contained in the byte stream of a Class file complies with all the constraints of the Java Virtual Machine Specification and that the information can be run as code without compromising the security of the virtual machine itself.

The virtual machine should throw a java.lang.VerifyError or one of its subclasses if it verifies that the input byte stream does not conform to the Class file format. The verification phase will roughly complete the following four stages of verification: file format verification, metadata verification, bytecode verification and symbol reference verification.

To prepare

Stage is formally defined as a class variable (namely static variables, by static modified variable) allocates memory and set up the class variables in the stage of initial value, conceptually, the memory used by these variables should be distributed in the method, but must pay attention to the method of area itself is a logical area, before the JDK 7 and, When HotSpot uses persistent generation to implement a method area, the implementation is entirely logical; In JDK 8 and later, Class variables are stored in the Java heap along with Class objects, so “Class variables in the method area” is simply a logical statement

parsing

The parsing phase is the process by which the Java virtual machine replaces symbolic references in the constant pool with direct references. The parse action is mainly performed for the class or interface, field, class method, interface method, method type, method handle, and call point qualifier, which correspond to the eight constant types of the constant pool:

  • CONSTANT_Class_info
  • CONSTANT_Fieldref_info
  • CONSTANT_Methodref_info
  • CONSTANT_InterfaceMethodref_info
  • CONSTANT_MethodType_info
  • CONSTANT_MethodHandle_info
  • CONSTANT_Dynamic_info
  • CONSTANT_InvokeDynamic_info

Initialize the

The initialization stage of a class is the last step in the class loading process. The previous class loading actions are completely controlled by the Java VIRTUAL machine, except that the user application can partially participate in the loading stage through a custom class loader. It is not until the initialization phase that the Java virtual machine actually executes the Java program code written in the class, handing control to the application program.

Class loader

The Java Virtual Machine design team intentionally implemented the class-loading action of “getting the binary stream describing a class by its fully qualified name” outside the Java Virtual machine so that the application could decide how to get the required classes. The code that implements this action is called a Class Loader.

Classes and class loaders

Although the class loader is only used to implement the loading action of the class, it plays a far more important role in Java programs than the class loading phase. For any class, the uniqueness of the Java virtual machine must be established by both the classloader that loads it and the class itself. Each classloader has a separate class namespace. This sentence can express more popular: compare whether the two classes “phase”, only in these two classes are from the same Class loader under the premise of load to be meaningful, otherwise, even if these two classes derived from the same Class files, by the same Java virtual machine loading, as long as the load they’re different Class loaders, these two classes are not necessarily equal.

Parental delegation model

From the perspective of Java virtual machines, there are only two different class loaders: one is the Bootstrap ClassLoader, which is implemented in C++ and is part of the virtual machine itself; The other is all the other classloaders, which are implemented in the Java language, exist independently of the virtual machine, and all inherit from the abstract java.lang.classloader class.

Bootstrap Class Loader: This class loader is responsible for loading the

\lib directory, or the path specified by the -xbootclasspath parameter, and is recognized by the Java virtual machine (recognized by the file name, such as rt.jar, tools.jar, Libraries with incorrect names will not be loaded even if placed in the lib directory.) The libraries are loaded into the virtual machine memory.

Extension ClassLoader: This ClassLoader is implemented as Java code in sun.misc.Launcher$ExtClassLoader. It is responsible for loading all libraries in the

\lib\ext directory, or in the path specified by the java.ext.dirs system variable.

Application ClassLoader: This ClassLoader is implemented by sun.misc.Launcher$AppClassLoader. Because the application ClassLoader is the return value of the getSystemClassLoader() method in the ClassLoader class, it is also called the “system ClassLoader” in some cases. It is responsible for loading all libraries on the user’s ClassPath, and developers can use the class loader directly in their code. If the application does not have its own custom class loader, this is generally the default class loader in the application.

Java applications prior to JDK 9 were loaded by a combination of these three types of loaders. If necessary, users can expand by adding custom Class loaders, such as adding a Class file source other than the disk location, or using Class loaders to isolate and reload classes. The collaboration between these classloaders is “usually” shown in the diagram.

The hierarchical relationship between the various class loaders shown in the figure above is referred to as the “Parent Delegation Model” for class loaders. The parent delegate model requires that all class loaders have their own parent class loaders, except for the top-level start class loaders. However, the parent-child relationship between classloaders is not usually implemented in an Inheritance relationship, but usually uses Composition relationships to copy the code of the parent loader.

The working process of the parental delegation model: If a classloader receives a class-loading request, it first does not attempt to load the class itself. Instead, it delegates the request to the parent classloader. This is true at every level of classloaders, so all load requests should eventually be sent to the top level of the starting classloader. Only when the parent loader reports that it cannot complete the load request (it does not find the desired class in its search scope) will the child loader attempt to complete the load itself.

Parent-delegate model benefits: One of the obvious benefits of using the parent-delegate model to organize relationships between class loaders is that classes in Java have a hierarchy of priorities along with their classloaders. For example, the java.lang.Object class, which is stored in rt.jar, is delegated to the boot class loader at the top of the model by any class loader. Therefore, the Object class is guaranteed to be the same class in each class loader environment of the program. On the other hand, instead of using the parent delegate model and having each class loader load it, if the user wrote a class named java.lang.Object and put it in the program’s ClassPath, the system would have multiple Object classes. The most basic behavior in the Java type system is not guaranteed, and applications become chaotic.

[1] “Deep Understanding of JVM Virtual Machines”

This article has participated in the activity of “New person creation Ceremony”, and started the road of digging gold creation together.