class loader mechanism

class loading mechanism

Types of class loaders:

  • Start the class loader
  • extension class loader
  • system class loader

The startup class loader and extension class loader have no parent class loader, while the parent class loader of the system class loader is the extension class loader, and the parent class loader of the custom class loader is the extension class loader

The so-called class loading: is the process of creating the class object corresponding to the .class file and loading the class file into the memory.

The class loading process is mainly divided into three steps:

1. Load: Find the .class file of the class and create a class object

2. Links: In three small steps:

  • Verification: Verify whether the information in the class file meets the requirements of the virtual machine;
  • Preparation: Static variables allocate memory and set initialization values, excluding final-modified static variables, final variables will be initialized at compile time, and instance variables will not be included. Static variables are class variables, which will be allocated in the method area, and the instance variable will be allocated in the method area. Variables are allocated on the heap along with the object;
  • Analysis: Replace the symbolic reference in the constant pool with a direct reference, that is, with a pointer directly to the target, a relative offset, or a handle indirectly positioned to the target;

3. Initialization: If there is a parent class, initialize the parent class, execute static initializers, static variables (only default values ​​are given in the preparation stage), and initialize the original variables.

ClassLoader source code analysis

The loadClass method is used to load the class file, where the class loading mechanism is assumed to involve the parent delegation mechanism.

Parent delegation mechanism: that is, when the child class loader receives a class loading request, it will submit it to the parent class loader for processing. If there is a parent class loader above the parent class loader, it will continue to recurse and find the final parent class loader to load , when the parent class loader fails to load the class, it will be loaded by the findClass() method in the child class loader.

The purpose of the parental delegation mechanism is to:

1. This hierarchical relationship with priority can prevent classes from being loaded repeatedly. When the parent class loader is loaded, the subclass does not need to be loaded;

2. Ensure the security of class loading: For example, if the core Api library is tampered with and the parent class loader is loaded, an error will be reported directly.

protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
 {
    synchronized (getClassLoadingLock(name)) {
    //First check whether the class has been loaded
    Class<?> c = findLoadedClass(name);
    if (c == null) {
        long t0 = System.nanoTime();
        try {
            //If the class is not loaded and there is a parent class loader, then according to the parent delegation mechanism, look for the parent class loader to load
            //If no parent class loader exists, look for the startup class loader to load
            if (parent != null) {
                c = parent.loadClass(name, false);
            } else {
                c = findBootstrapClassOrNull(name);
            }
        } catch (ClassNotFoundException e) {
            // ClassNotFoundException thrown if class not found
            // from the non-null parent class loader
        }
        if (c == null) {
            //c==null indicates that the parent class/startup class loader does not find the class, and the findClass() method is called at this time
            long t1 = System.nanoTime();
            //This findClass method will be implemented by the subclass, that is, when the parent class loader fails to load, the subclass loader is responsible for loading
            c = findClass(name);
            // this is the defining class loader; record the stats
            sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
            sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
            sun.misc.PerfCounter.getFindClasses().increment();
         }

     }
     if (resolve) { //Whether to parse the class, the native method is called
            resolveClass(c);
      }
       return c;
    }
 }

Tags: Java

Posted by X74SY on Wed, 18 May 2022 20:32:33 +0300