Loading subsystems such as JVM and parent delegation mechanism

Loading subsystems such as JVM and parent delegation mechanism

One, class loading subsystem

1. The class loading subsystem is responsible for loading class files from the file system or the network. The class file has a specific file identifier at the beginning of the file . The JVM does not .classjudge whether it needs to be loaded by checking whether the file suffix is ​​not , but through the beginning of the file. The specific file mark is the hexadecimal CA TE BA BE;

2. The loaded Class information is stored in a memory space that becomes the method area . In addition to class information, the method area also stores runtime constant pool information, and may also include string literals and numeric constants (this part of constant information is the memory mapping of the constant pool part of the Class file)

Here is a classic JVM memory structure diagram: the working range of the class loader is limited to the left half of the figure below, and does not include the instantiated objects by calling the constructor

  • Definition: Class loading refers to reading the binary data in the .class file of the class into memory, placing it in the method area of ​​the runtime data area, and then creating a java.lang.Class object in the heap area. Used to encapsulate the data structure of the class in the method area
    Insert picture description here

3. ClassLoader is only responsible for the loading of class files. As for whether it can run, it is determined by Execution Engine

4. If the constructor is called to instantiate the object, its instance is stored in the heap area

Functional breakdown
Insert picture description here

Load module

1. Obtain the binary byte stream that defines this class through the fully qualified name of a class;

2. Convert the static storage structure represented by this byte stream into runtime data in 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

The link module is divided into three parts, namely verification, preparation, and analysis

verification

1. The purpose is to ensure that the information contained in the byte stream of the Class file meets the requirements of the current virtual machine, to ensure the correctness of the loaded class, and not to endanger the safety of the virtual machine itself.

2. It mainly includes four verifications, file format verification, source data verification, bytecode verification, and symbol reference verification.

ready

1. Allocate memory for the class variable and set the default initial value of the class variable, that is, the zero value;

2. The static modified with final is not included here, because final will be allocated during compilation and will be explicitly initialized in the preparation phase;

3. The instance variable will not be allocated and initialized, 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.

Parsing

1. The process of converting symbol references in the constant pool into direct references.

2. In fact, the parsing operation is often accompanied by the JVM after the initialization is executed

3. Symbol reference is a set of symbols to describe the referenced target. The literal form of symbol application is clearly defined in the class file format of "Java Virtual Machine Specification". A direct reference is a pointer that directly points to the target, a relative offset, or a handle that is indirectly located to the target

4. The parsing action is mainly for classes or interfaces, fields, class methods, interface methods, method types, etc. Corresponding to CONSTANT_Class_info/CONSTANT_Fieldref_info, CONSTANT_Methodref_info, etc. in the constant pool.

Initialize the module, the initialization phase is the process of executing the class constructor method clinit()

1.clinit() means "class or interface initialization method", note that he does not refer to the constructor init()

2. This method does not need to be defined, it is the javac compiler that automatically collects the assignment actions of all class variables in the class and merges the statements in the static code block.

3. We noticed that if there is no static variable c, then there will be no clinit method in the bytecode file

Insert picture description here
The way the java program uses the class is divided into: active use and passive use, that is, whether the clinit() method is called

Actively use the third stage initialization (initialization module) in the class loading system, that is, the clinit() method is called in the initialization phase

And passive use will not call

Active use, divided into seven situations

1. Create an instance of the class

2. Access static variables of a certain type or interface, or assign values ​​to static variables

3. Call the static method of the class

4. Reflection such as Class.forName(com.dsh.jvm.xxx)

5. Initialize a subclass of a class

6. The class that is marked as the startup class when the java virtual machine is started

7. The dynamic language support provided by JDK 7: the analysis result of java.lang.invoke.MethodHandle instance REF_getStatic, REF_putStatic, REF_invokeStatic handle corresponding to the class is not initialized, then initialize

Except for the above seven cases, other methods of using java classes are regarded as passive use of classes and will not lead to class initialization.

The virtual machine must ensure that the clinit() method of a class is synchronized and locked under multiple threads

Types of class loaders

Insert picture description here

That is, a class only needs to be clinit once, and then the internal information of the class is stored in the method area.

  • Role: load class files, reference in the stack, specific examples in the heap
  • The virtualizer comes with three types of loaders
    • Start class (root) loader
    • Extended class loader
    • Application loader (system class loader)
      note:
  • There are many kinds of Class Loaders, three or four (the fourth one is the loader defined by yourself and inherits the ClassLoader ). The three that come with the system are:
  1. Bootstrap, written in C++

    • This class loading is implemented in C/C++ language and is nested inside the JVM
    • It is used to load the core java library (JAVA_HOME/jre/lib/rt.jar/resources.jar or the content under the sun.boot.class.path path), and is used to provide the classes needed by the JVM itself
    • Does not inherit from java.lang.ClassLoader, there is no parent loader
    • Load extension classes and application class loader, and designate as their parent loader, that is, ClassLoader
    • For security reasons, BootStrap startup class loader only loads classes whose package names start with java, javax, sun, etc.
  2. Extension class loader (Extension), written in Java

    • Written in java language and implemented by sun.misc.Launcher$ExtClassLoader.
    • Derived from the ClassLoader class, not inherited
    • Load the class library from the directory specified by the java.ext.dirs system property, or load the class library from the jre/lib/ext subdirectory (extension directory) of the JDK installation directory. If the JAR created by the user is placed in this directory, it will also be automatically loaded by the extended class loader
  3. Application Class Loader (AppClassLoader)

    • Written in java language and implemented by sun.misc.Launcher$AppClassLoader.
    • Derived from the ClassLoader class, not inherited
    • 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

    User-defined class loader:

    In daily Java application development, the loading of classes is almost performed by the coordination of the above-mentioned three types of loaders. If necessary, you can customize the class loaders to customize the way the classes are loaded.

    Why do you want to customize the class loader?

    • Load class in isolation
    • Modify the class loading method
    • Extension loading source
    • Prevent source code leaks

What we create when we are new is the application class loader (AppClassLoader).

public class Car {
    
    
    public static void main(String[] args) {
    
    
        Car car1 = new Car();
        Car car2 = new Car();
        Car car3 = new Car();

        System.out.println(car1.hashCode());
        System.out.println(car2.hashCode());
        System.out.println(car3.hashCode());

        Class<? extends Car> aClass = car1.getClass();

        System.out.println(aClass.getClassLoader());    // 应用程序加载器 AppClassLoader
        System.out.println(aClass.getClassLoader().getParent()); // 扩展类加载器 ExtClassLoader       D:\jdk1.8\jre\lib\ext/*.jar
        System.out.println(aClass.getClassLoader().getParent().getParent());  // null   1. 不存在, 2. java程序获取不到  D:\jdk1.8\jre\lib\rt.jar

    }

note:

  • If it is the JDK's own classes (Object, String, ArrayList, etc.), the loader used is the Bootstrap loader; if you write your own class, the AppClassLoader loader is used; the Extension loader is the program responsible for updating java The class loading of the package is carried out
  • In the output, sun.misc.Launcher is the entry program for JVM related calls
  • The number of Java loaders is 3+1. The first three are built in the system, users can customize the way the class is loaded by inheriting Java. lang. ClassLoader

JVM indicates whether two class objects are the same class

1. Two necessary conditions for whether two class objects exist in the same class in jvm

  • The complete class name of the class must be consistent , including the package name
  • Even if the complete class name of the class is the same, it is required that the ClassLoader (referring to the ClassLoader instance object) that loads this class must be the same ; whether it is the boot class loader or the definition of the class loader

2. In other words, in jvm, even if these two class objects (class objects) source from the same Class file and are loaded by the same virtual machine, as long as the ClassLoader instance objects that load them are different, then these two class objects It is also not equal.

3. For the reference to the class loader, the JVM must know whether a type is loaded by the startup class loader or the user class loader. If a load type by the user class loader, then the JVM will be a reference to the class loader as part of the type of information stored in the method area . When resolving references from one type to another, the JVM needs to ensure that the loaders of the two types are the same.

2. Parental delegation mechanism

Insert picture description here
note:

  • Parental delegation mechanism: "My dad is Li Gang, ask my dad for something."
    For example: if you need to use a class A.java, first go to the top Bootstrap root loader to find it. If you find it, you can use it. If you can't find it, go down one more level. Go to the Extension loader to find it. For another layer, go to the AppClassLoader to find it, and use it if you find it. If you can't find it, it will report "CLASS NOT FOUND EXCEPTION".
//测试加载器的加载顺序
package java.lang;

public class String {
    
    

    public static void main(String[] args) {
    
    

        System.out.println("hello world!");

    }
}

/*
* output:
* 错误: 在类 java.lang.String 中找不到 main 方法
* */

The above code is to test the order of the loader: the Bootstrap loader is loaded first. Since there is a java.lang.String class in the JVM, this class will be loaded first instead of the class written by yourself, and this class does not main method, so it will report "Cannot find main method in class java.lang.String".

This question involves, if there are two identical classes, which one will Java use? If you use the user-defined java.lang.String, then do not use this type of program will go to all errors. Therefore, in order to ensure that the source code written by the user does not pollute the source code that comes with the java factory, a kind of " parents " is provided. "Delegation" mechanism to ensure "sandbox security" . That is, find it first and use it first.

Insert picture description here

Guess you like

Origin blog.csdn.net/qq_43803285/article/details/115281657