The introduction

When learning about the virtual machine class loading mechanism, we have learned that the virtual machine loads the data describing the class from Claas file into memory, and verifies, converts, parses, and initializes the data, finally forming Java types that can be directly used by the virtual machine. The entire life cycle goes through stages of load -> Verify -> Prepare -> parse -> initialize -> use -> unload, and load is a phase of class loading that does three things:

  1. Gets the binary byte stream that defines a class by its fully qualified name.
  2. Transform the static storage structure represented by this byte stream into the runtime data structure of the method area.
  3. Generates an in-memory representation of this classjava.lang.ClassObject that acts as an access point to the various data of the class called the method area.

Class loader

Class to class loader relationship

The class loader implements the action of obtaining the binary byte stream that defines a class by its fully qualified name during the load phase. Each class loader has a separate class namespace. It makes sense to compare two classes under the same class loader. Otherwise, classes under different class loaders must be different. So, for any class, it needs to be verified in the virtual machine by the classloader that loads it and by the class itself.

Class loader classification

Most Java programs use three system-provided class loaders: the launcher class loader, the extension class loader, and the application class loader.

Start the class loader

Bootstrap ClassLoader Loads recognized libraries (such as rt.jar) stored in the %JAVA_HOME%/lib directory or in the path specified by the -xbootclasspath parameter to the VM memory. The boot class loader cannot be directly referenced by the Java VM. If you need to delegate the loading request to the boot class loader when writing a custom class loader, use NULL instead.

Extend the class loader

Sun.misc.Launcher$ExtClassLoader Responsible for loading all libraries in the %JAVA_HOME%/lib/ext directory or in the path specified by the java.ext.dirs system variable, developers can use the extended class loader directly.

Application class loader

The Application ClassLoader is implemented by sun.misc.Launcher$ExtClassLoader, which is the return value of the getSystemClassLoader() method in the ClassLoader. The system class loader, commonly referred to as the system class loader, is responsible for loading libraries specified on the user’s ClassPath and can be used directly by the developer. This is the default class loader for an application that does not have its own custom class loader.

Parental delegation model

introduce

As shown in figure, the hierarchical relationships between the class loader delegation model, known as the class loader parents parents delegation model requirements in addition to the start of the top class loader, the rest of the class loader should have its own parent class loader, parent-child relationships between class loaders tend not to inherit relationship, but is used by loader code reuse father combination relations.

The working process

  1. If a classloader receives a classload request, it first delegates the request to the parent classloader (searching for the desired class) rather than trying to load the class itself.
  2. The class loader at each level delegates requests to the parent class loader.
  3. Eventually, all load requests should be passed to the top layer of the bootstrap class loader, and the child loader will try to load it itself unless the parent says it can’t complete the load request.

advantage

  1. A Java class has a hierarchical relationship with priority along with its classloader. Such asrt.jarClass stored injava.lang.ObjectNo matter which class loader loads the class, it is ultimately delegated to the boot class loader at the top of the model for loading. The Object class is the same class in the various logger environments of the program.
  2. On the other hand, if the parent delegate model is not used, if the user writes a code with the same namejava.lang.ObjectClasses are stored in the ClassPath of the program, and multiple Object classes will appear in the system when each class is loaded automatically.

implementation

public abstract class ClassLoader {
    // Delegate's parent class loader
    private final ClassLoader parent;

    publicClass<? > loadClass(String name)throws ClassNotFoundException {
        return loadClass(name, false);
    }

    protectedClass<? > loadClass(String name,boolean resolve) throws ClassNotFoundException {
        synchronized (getClassLoadingLock(name)) {
            // First, check whether the class is loadedClass<? > c = findLoadedClass(name);if (c == null) {
                try {
                    if(parent ! =null) {
                    	// If the parent loader is not empty, use the parent loader
                        c = parent.loadClass(name, false);
                    } else {
                    	// If the parent class loader is empty, the initiator class loader is used as the parent class loaderc = findBootstrapClassOrNull(name); }}catch (ClassNotFoundException e) {
                    // If the parent class loader throws a ClassNotFoundException,
                    // The parent class loader cannot complete the load request
                }

                if (c == null) {
    				// The parent class loader cannot complete the load request
    				// Call its own findClass() method for class loadingc = findClass(name); }}if (resolve) {
                resolveClass(c);
            }
            returnc; }}protectedClass<? > findClass(String name)throws ClassNotFoundException {
        throw newClassNotFoundException(name); }}Copy the code

The implementation of the parent delegate model is centralized in the loadClass() method of java.lang.classLoader.

  1. Check if it has already been loaded. If not, call the parent loaderloadClass()Methods.
  2. If the parent class loader is empty, the startup class loader is used as the parent class loader by default.
  3. Throws if the parent class loader fails to loadClassNotFoundExceptionAfter the exception, call its ownfindClass()Method to load.

Refer to Zhou Zhiming. In-depth Understanding of Java Virtual Machine