[big data Java foundation - JVM 03] class loading subsystem class loader subsystem

Posted by semsem on Sun, 24 Oct 2021 21:58:15 +0200

Class loader subsystem

1.1 what is a class loading subsystem?

The Class loader subsystem is responsible for loading Class files from the file system or network. The Class file has a specific file ID (magic number) at the beginning of the file.

The Class loader subsystem (ClassLoader) is only responsible for loading the Class file. Whether it can run or not is determined by the Execution Engine.

|   Your mother [ClassLoader] found a blind date for you [Execution Engine]. Whether it can be done depends on your own ability

The information of the loading Class is stored in a memory space called the method area. In addition to Class information, the method area also stores runtime constant pool information, possibly including string literal and numeric constants (this part of constant information is the memory mapping of constant pool in Class file)

|   Runtime constant pool: the constant pool is loaded into memory at runtime, which is called runtime constant pool

Architecture diagram of class 1.2 loading subsystem

   

Loading process of class 1.3

1.3.1 loading

Get the binary byte stream defining a class through the fully qualified name of the class.

The static storage structure represented by this byte stream is transformed into the runtime data structure of the method area.

A java.lang.Class object representing this class is generated in memory as an access to various data of this class in the method area

|   How to load. class files

  • Load directly from local system
  • Get through the network, typical scenario: Web Applet
  • Read from the zip package, which is called the foundation of jar and war format in the future
  • Dynamic agent technology (reflection dynamic agent) is the most used in runtime calculation generation
  • Generated by other files, typical scenario: JSP Application
  • It is rare to extract. class files from proprietary databases
  • Obtain from encrypted files. Typical protection measures against decompilation of Class files

1.3.2 links

verification

  • 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, ensure the correctness of the loaded Class, and will not endanger the safety of the virtual machine.
  • It mainly includes four kinds of verification, file format verification, source data verification, bytecode verification and symbol reference verification.

get ready

  

  • Allocate memory for class variables and set the default initial value of such variables, i.e. zero value;

  • static modified with final is not included here, because final will be allocated during compilation and will be explicitly initialized in the preparation stage;
  • There is no initialization for instance variables. Class variables are allocated in the method area, and instance variables are allocated to the java heap along with the object.

analysis

  • The process of converting a symbolic reference in a constant pool to a direct reference.

|   Symbol reference: a set of symbols to describe the referenced target. The literal form of symbol reference is clearly defined in the Class file format of java virtual machine specification.

|   Direct reference: a pointer directly to the target, a relative offset, or a handle indirectly positioned to the target

  • In fact, the parsing operation is often accompanied by the jvm executing after initialization
  • Parsing actions are mainly for classes or interfaces, fields, class methods, interface methods, method types, etc. Corresponding to constant in constant pool_ Class_ info,CONSTANT_Fieldref_info,CONSTANT_Methodref_info et al.

1.3.3 initialization: initialize the module. The initialization phase is the process of executing the class constructor method < clinit > ()

< clinit > is "class or interface initialization method". It does not refer to the constructor (the constructor is < init > () from the perspective of virtual machine).

This method does not need to be defined. It is a combination of the assignment actions of all class variables in the class automatically collected by the javac compiler and the statements in the static code block.

|   < clinit > () is not defined, but the < clinit > () method exists in the binary file

|   If there is no assignment to the variable and no static code block, there will be no < clinit > () method  

|   Forward reference

  1. If the class has a parent class, the JVM will call the < clinit > method of the parent class first, and then the < clinit > method of the child class
  2. The virtual machine must ensure that the < clinit > method of a class is locked synchronously under multithreading

|   A class will only be loaded once, that is, the < clinit > method will only be called once. After the class is loaded for the first time, it will be cached in memory. Next time, use this class and get it directly from memory.

|   For example: suppose there are two threads th1 and th2 that want to load the class TestClass. If thread th1 grabs the statement of loading the class TestClass t = new TestClass(), th1 loads the class. Because it will be locked synchronously, th2 cannot enter the method of loading the class, so only one thread can successfully print the initialization statement

  

Class 1.4 loader classification

1.4.1 boot class loader: BootStrap ClassLoader

It is implemented by C/C + + language and nested inside the JVM.

java core class libraries are loaded using the bootstrap classloader.

It does not inherit from ClassLoader and has no parent loader.

Load the extension class loader and application class loader, and specify their parent class loader, that is, ClassLoader.

For security reasons, the Bootstrap startup class loader only loads packages with package names beginning with java, javax, sun, etc

1.4.2 custom class loader:

Implemented by Java.

The Java virtual machine specification divides all class loaders derived from the abstract class ClassLoader into custom class loaders. As can be seen from the following figure, the Extension Class Loader ExtClassLoader and the application class loader System ClassLoader indirectly inherit the ClassLoader. Therefore, Extension Class Loader and System ClassLoader are also custom class loaders.

 

Note that the loader partition relationship in the above figure is an inclusion relationship, not an upper and lower layer, nor an inheritance relationship. (the custom class loader written in Java language will not inherit the BootStrap ClassLoader implemented in C/C + +, which is similar to the hierarchy).

Extension class loader: the JVM comes with it

  • Written in java language and implemented by sun.misc.Launcher$ExtClassLoader
  • Derived from ClassLoader class
  • Load the class library from the directory specified by the java.ext.dirs system attribute, or 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

Application class loader (System Class Loader): the JVM comes with it

  • Written in java language and implemented by sun.misc.Launcher$AppClassLoader.
  • Derived from ClassLoader class
  • It is responsible for loading the class library under the path specified by the environment variable classpath or the system attribute java.class.path
  • This class loader is the default class loader in the program. Generally speaking, the classes of java applications are loaded by it
  • This class loader can be obtained through the ClassLoader#getSystemClassLoader() method

Programmer custom class loader

Why customize the class loader?

  • Isolate loading classes: ensure that the framework jar package does not conflict with the middleware jar package
  • Prevent source code leakage
  • Extended load source
  • Modify the method of class loading: load dynamically when necessary

How to customize the class loader?

  • Inherit ClassLoader class
  • If the requirements are not complex, you can also directly inherit the URLClassLoader class, which can avoid writing the findClass() method and its way to obtain the byte code stream, making the writing of the custom class loader more concise
  • Load the custom class into the logic and unload the findClass() method (loaderClass() method needs to be rewritten before JDK1.2. It is not recommended to override loaderClass() after JDK1.2, but to override findClass())

  Get loader code demonstration of different classes    

/**
 * ClassLoader load
 */
public class ClassLoaderTest {
    public static void main(String[] args) {
        //Get system class loader
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2

        //Gets its upper level extension class loader
        ClassLoader extClassLoader = systemClassLoader.getParent();
        System.out.println(extClassLoader);//sun.misc.Launcher$ExtClassLoader@610455d6

        //Failed to get the boot class loader on its upper layer
        ClassLoader bootStrapClassLoader = extClassLoader.getParent();
        System.out.println(bootStrapClassLoader);//null

        //For user-defined classes: use the system class loader to load
        ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
        System.out.println(classLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2

        //The String class is loaded using the boot class loader -- > the Java core class libraries are loaded using the boot class loader
        ClassLoader classLoader1 = String.class.getClassLoader();
        System.out.println(classLoader1);//null cannot be obtained, which indirectly proves that the String class is loaded using the bootstrap class loader

    }
}
/**
 * Virtual machine comes with loader
 */
public class ClassLoaderTest1 {
    public static void main(String[] args) {
        System.out.println("********Start class loader*********");
        
        // 1. Obtain the api path that BootStrapClassLoader can load
        URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
        
        /*
            Print results
            file:/E:/software/java/java/jdk/jdk1.8.0_131/jre/lib/resources.jar
            file:/E:/software/java/java/jdk/jdk1.8.0_131/jre/lib/rt.jar
            file:/E:/software/java/java/jdk/jdk1.8.0_131/jre/lib/sunrsasign.jar
            file:/E:/software/java/java/jdk/jdk1.8.0_131/jre/lib/jsse.jar
            file:/E:/software/java/java/jdk/jdk1.8.0_131/jre/lib/jce.jar
            file:/E:/software/java/java/jdk/jdk1.8.0_131/jre/lib/charsets.jar
            file:/E:/software/java/java/jdk/jdk1.8.0_131/jre/lib/jfr.jar
            file:/E:/software/java/java/jdk/jdk1.8.0_131/jre/classes
        */
        for (URL e:urls){
            System.out.println(e.toExternalForm());
        }

        // 2. Randomly select a class from the above path to see what its class loader is
        //The Provider is located in / jdk1.8.0_171.jdk/Contents/Home/jre/lib/jsse.jar
        ClassLoader classLoader = Provider.class.getClassLoader();
       
        // 3. The boot class loader cannot get the class. If it is null here, it can also indicate that the class is obtained by the boot class loader
        System.out.println(classLoader);//null

        System.out.println("********Extended class loader********");
        // The extension class loader loads the class library from the directory specified by the java.ext.dirs system property    
        String extDirs = System.getProperty("java.ext.dirs");
    
        // E:\software\java\java\jdk\jdk1.8.0_131\jre\lib\ext
        // C:\Windows\Sun\Java\lib\ext
        for (String path : extDirs.split(";")){
            System.out.println(path);
        }
        //Select a class randomly from the above path to see what its classloader is: extended classloader
        ClassLoader classLoader1 = CurveDB.class.getClassLoader();
        System.out.println(classLoader1);//sun.misc.Launcher$ExtClassLoader@4dc63996
    }
}

1.5 ClassLoader

  1. Abstract classes. Except for the startup class loader, all other class loaders inherit directly or indirectly from ClassLoader.

  1. Common methods of ClassLoader
  2. Ways to get ClassLoader:
  • Get the ClassLoader of the current class: clazz.getClassLoader()
  • Gets the ClassLoader of the current thread context: Thread.currentThread.getContextClassLoader()
  • Get the ClassLoader of the system: ClassLoader.getSystemClassLoader()
  • Get the caller's ClassLoader: DriverManager.getCallerClassLoader()

Topics: Java Big Data