Understand the Java class loading mechanism

1. What is the class loading mechanism

The JVM virtual machine loads the data describing the class from the Class bytecode file into the memory, and verifies, converts, parses and initializes the data, and finally forms a java type that can be directly used by the virtual machine. This is the class loading of the virtual machine. mechanism.

2. Class loading process

The java class loading, linking and initialization processes are all completed during the running of the program
1. The class loading life
insert image description here
cycle is divided into 7 stages as shown in the class loading life cycle. The 5 stages of loading, verification, preparation, initialization and unloading must be in accordance with this The sequence begins step by step.
1.1 Loading
At this stage, the virtual machine does three things
1) Gets the binary byte stream that defines this class by its fully qualified name.
2) Convert the static storage result represented by this byte stream into the runtime data structure of the method area.
3) Generate a java.lang.Class object representing this class in memory as the access entry for various data of this class in the method area. (Note: This does not necessarily have to be obtained from a Class file. It can be read from a ZIP package (such as from a Jar package and a war package), or calculated and generated at runtime (dynamic proxy), or it can be generated by Other file generation (such as converting the JSP file to the corresponding Class class)).
1.2 Verification
This stage is only to ensure whether the information contained in the byte stream of the Class file meets the requirements of the current virtual machine, and will not endanger the security of the virtual machine itself.
The verification is mainly verified from four aspects, file format verification, metadata verification, bytecode verification, and symbol reference verification.

1.2 Preparation
This stage is the stage of formally allocating memory for class variables and setting the initial value of class variables, that is, allocating the memory space used by these variables in the method area. The initial value concept mentioned here, for example, a class variable is defined as:
public static int v =123;
In fact, the initial value of the variable V after the preparation stage is 0 instead of 123, and the put static instruction that assigns V to 123 is a program After being compiled, it is stored in the class constructor method.
But note that if it is declared as
public static final int v =123;
the ConstantValue property will be generated for v in the compilation phase, and the virtual machine will assign v to 123 according to the ConstantValue property in the preparation phase.

1.3 Parsing
This stage is the process in which the virtual machine replaces the symbolic references in the constant pool with direct references. The parsing action is mainly performed on 7 types of symbolic references, namely class or interface, field, class method, interface method, method type, method handle and call site qualifier.
1.3.1 Symbolic references:
Symbolic references have nothing to do with the layout of the virtual machine implementation, and the referenced target does not necessarily have to be loaded into memory. The memory layout of various virtual machine implementations can be different, but the symbolic references they can accept must be consistent, because the literal form of symbolic references is clearly defined in the Java Virtual Machine Specification's Class file format
1.3.2 Direct reference:
A direct reference can be a pointer to the target, a relative offset, or a handle that can be located indirectly to the target. If there is a direct reference, the target of the reference must already exist in memory.
1.4 Initialization:
The initialization stage is the last stage of class loading. After the previous class loading stage, except that the class loader can be customized in the loading stage, other operations are dominated by the JVM. At the initial stage, the actual execution of the Java program defined in the class begins.
The initialization phase is the process of executing the class constructor methods. A method is a combination of assignment operations of class variables in a class automatically collected by the compiler and statements in a static statement block. The virtual machine ensures that the method of the parent class has been executed before the child method is executed. If there is no static variable assignment or static statement block in a class, the compiler may not generate the () method for this class.

Note that class initialization is not performed in the following cases:

  1. Referencing the static fields of the parent class through the subclass will only trigger the initialization of the parent class, not the subclass.
  2. Defining an array of objects does not trigger initialization of the class.
  3. Constants are stored in the constant pool of the calling class during compilation. Essentially, there is no direct reference to the class that defines the constant, and the class where the constant is defined will not be triggered.
  4. Obtaining the Class object by the class name will not trigger the initialization of the class.
  5. When loading the specified class through Class.forName, if the specified parameter initialize is false, the class initialization will not be triggered. In fact, this parameter tells the virtual machine whether to initialize the class.
  6. Through the default loadClass method of ClassLoader, the initialization action will not be triggered.

3. Class loader

JVM provides three class loaders
1. Bootstrap ClassLoade
is responsible for loading the JAVA_HOME\lib directory, or in the path specified by the -Xbootclasspath parameter, and recognized by the virtual machine (identified by file name, such as rt. jar) class.
2. The Extension ClassLoader
is responsible for loading the class library in the JAVA_HOME\lib\ext directory, or in the path specified by the java.ext.dirs system variable.
3. The application class loader (Application ClassLoader)
is responsible for loading the class library on the user path (classpath). JVM loads classes through the parent delegation model. Of course, we can also implement custom class loaders by inheriting java.lang.ClassLoader

Parent delegation model
Avoid the same class being loaded multiple times;
each loader can only load classes within its own scope;
insert image description here
when a class receives a class loading request, it will not try to load the class by itself first, but will put the request Delegate to the parent class to complete, this is the case for each hierarchical class loader, so all load requests should be passed to the startup class loader, only when the parent class loader reports that it cannot complete the request (at its loading The class to be loaded is not found in the path), the subclass loader will try to load it by itself.
One advantage of using parental delegation is that, for example, when loading the class java.lang.Object located in the rt.jar package, no matter which loader loads this class, it is ultimately delegated to the top-level startup class loader for loading, which ensures that Using different class loaders will end up with the same Object object.
insert image description here
insert image description here
There is an interview question: Can you write a String class yourself
Answer: No, because according to the parent delegation mechanism of class loading, the parent class will be loaded, and the parent class will not load the String if it finds a conflict;

4. Summary

I have sorted out and sorted out the Java class loading mechanism. It is indispensable to have a deep understanding of JAVA. I summarize an article every day to strive for greater progress.
Reference:
[1]: https://www.cnblogs.com/aspirant/p/7200523.html
[2]: "JAVA Core Knowledge Points"
[3]: "In-depth Understanding of Java Virtual Machine JVM Advanced Features and Best Practices" practice"

Guess you like

Origin blog.csdn.net/cjy_win/article/details/88716710