Class loader

What is a class loader

Class loader is a part of the Java runtime environment. It is mainly responsible for dynamically loading Java classes into the memory space of the Java virtual machine. To learn class loader, you need to master the Java delegation principle (parent delegation mechanism). The Java language is a dynamic interpreted language, and classes cannot run until they are loaded into the JVM. When the specified program is run, the JVM loads the compiled.class file into memory according to requirements and certain rules, organizing it into a complete Java application. This loading process is performed by the ClassLoader, specifically by the ClassLoader and its subclasses. The classloader itself is a class that essentially reads class files from hard disk into memory.

The type of class loader

BootstrapClassLoader

The startup class loader is the top-level Java class loader, responsible for loading the JDK’s core libraries, such as rt.jar, resources.jar, charsets.

The following program shows which JAR packages and associated class files are loaded

Select the Object class from rt.jar and view its classloader:

Why is the Object class loader null?

Because Bootstrap ClassLoader is written in C/C++ and is itself part of the virtual machine, it is not a JAVA class, that is, it cannot be referenced in JAVA code.

ExtensionClassLoader

Responsible for loading extension jar packages, jre/lib/ext/*.jar and jar packages specified by the java.ext.dirs system property, Jar packages placed in this directory are also visible to AppClaseLoder (because ExtClassLoader is the parent loader of AppClassLoader and Java classloader uses delegate mechanism)

AppClassLoader (Application class loader)

Is responsible for loading the classPath specified content or the JAR class package and classPath specified by the java.class.path system property or the classPath operating system property.

To see where the AppClassLoader is loaded, use the following code:

The following code shows that the class is loaded by AppClassLoader:

Class loading process

  1. Loading (Loding)

    The loading phase of a Class is when the classloader reads the binary byte stream of the Class based on its fully qualified name into the JVM and converts it into a real column of Class objects corresponding to the target Class, which will later serve as the various data access points for that Class in the method area.

  2. Linking

    The link stage is to integrate the class data of binary byte stream in JVM into the JVM runtime state through verification, preparation and parsing.

    • Verification

      Format verification: verify compliance with class file specifications;

      Semantic validation: Checks whether a type marked final contains subclasses; Check that final method videos ina class are overridden by subclasses. Make sure there are no incompatible method declarations between the parent and subclasses (for example, the method signature is the same but the method return value is different)

      Operation validation: Data in the operand stack must be operated on correctly, and various symbolic references in the constant pool are validated (usually in the parsing phase, checking whether the fully qualified name described in the rich reference is located to the specified type, and whether the access modifiers for the class member information allow access, etc.)

    • Preparation

      Allocate memory for all static variables in the class and set a default value for them (since the object has not been created, the variables in the real column cannot be manipulated); Static variables modified by final are assigned their original values;

    • Resolution

      Resolves symbolic references to classes, methods, attributes, and so on into direct references. The various symbolic references in the constant pool are resolved to direct references to Pointers, offsets, and other memory addresses

  3. Initializing

    The class initialization code is invoked to initialize static member variables, and if a static code block is executed, the JVM performs all operations defined in the static code block during the initialization phase.

Parents delegate

What is the parent delegate mechanism

Parent delegation is a bottom-up, bottom-up process of class loading.

1. When receiving the loading request, the class loader will first determine whether the class has been loaded, if so, it will end, otherwise it will entrust its parent loader to load, and continue to cycle this process until the loading task is assigned to the BootstrapClassLoader. The BootstrapClassLoader will determine whether the class can be loaded. If it can be loaded, it will load the class directly. Otherwise, it will give its own subclass loader to load the class. ClassNotFoundException.

Why parent delegation

  1. Mainly for safety.

    Imagine what would happen if someone, other than a parent delegate, wrote a String class and sent the username and password obtained by String to the other parent’s server remotely.

  2. Reduce the waste of resources.

    In order to avoid repeated loading, reduce the waste of resources.

lazyLoading

Technically, I think it’s more appropriate to call it lazyInitializing; The JVM specification does not specify when to load; But it’s very strict about when you have to initialize it;

When the class is initialized:

test

public class LaxyLoading {
    public static void main(String[] args) throws ClassNotFoundException {
        P p; // a
        X x= new X(); // b
        System.out.println(P.i); // c
        System.out.println(P.j); // d
    }
 
    public static class P{
        final static int i = 9;
        static int j = 10;
        static {
            System.out.println("Load class P"); }}public static class X extends P{
        static {
            System.out.println("Load class X"); }}}Copy the code

Keep only code A:

Nothing is printed, proving that the JVM-loaded class is lazy and will not be initialized without references.Copy the code

Just keep code B:

When you initialize a child class, the parent class is initialized firstCopy the code

Keep only code C:

Print: 9 // Prove that variables accessing final modifications are not initializedCopy the code

Keep only code D:

Print :(loading class P) (10) // prove that fetching a static variable class is initializedCopy the code