[In-depth understanding of JVM]: ClassLoader (ClassLoader) and parent delegation model

This article involves

Class loading

Each written ".java" extension class file stores the program logic that needs to be executed. These ".java" files are compiled by the Java compiler into a file with the extension name ".class".

jvmThe startup is done by creating an initial class by the bootstrap class loader, which is jvmspecified by the specific implementation. [From official specifications]

The ".class" file saves the converted virtual machine instructions of the Java code. When a class needs to be used, the virtual machine will load its ".class" file, create the corresponding class object, and load the class file To the memory of the virtual machine , this process is called class loading.

Class loading mechanism-parent delegation mechanism

Jvm uses an on-demand loading method for class files. When the class needs to be used, jvm will load its class files into memory to generate class objects.

When loading the class, it is used 双亲委派机制, that is, a task delegation mode that hands the request to the parent class for processing.

Implementation process:

Class loading during Java runtime

Learn about the more important methods in the ClassLoader class, which will be used in writing the echo in the exploit.

loadClass(String)

This method loads the binary type of the specified name (including the package name). This method is no longer recommended for users to rewrite after JDK1.2 but users can directly call this method. The loadClass() method is implemented by the ClassLoader class itself. The logic is the realization of the parental delegation model . The source code is as follows. loadClass(String name, boolean resolve) is an overloaded method. The resolve parameter represents whether to generate a class object and perform resolution related operations at the same time.

protected Class<?> loadClass(String name, boolean resolve)
      throws ClassNotFoundException
  {
      synchronized (getClassLoadingLock(name)) {
          // 先从缓存查找该class对象,找到就不用重新加载
          Class<?> c = findLoadedClass(name);
          if (c == null) {
              long t0 = System.nanoTime();
              try {
                  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) {
                  // If still not found, then invoke findClass in order
                  // 如果都没有找到,则通过自定义实现的findClass去查找并加载
                  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) {//是否需要在加载时进行解析
              resolveClass(c);
          }
          return c;
      }
  }

 

About loadClass(), findClass(), defineClass() difference

 

How to implement a ClassLoader

First inherit the ClassLoader class, and then overwrite the findClass (String name) method to complete a class loader with a parent delegation model.

protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // 查看是否已经加载过该类,加载过的类会有缓存,是使用native方法实现的
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    //父类不为空则先让父类加载
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                    //父类是null就是BootstrapClassLoader,使用启动类类加载器加载
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // 父类类加载器不能加载该类
                }

                //如果父类未加载该类
                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    long t1 = System.nanoTime();
                    //让当前类加载器加载
                    c = findClass(name);
                }
            }
            return c;
        }
    }

In the classic template method mode, subclasses only need to implement findClass and care about where they are loaded.

One more point, the parent needs to be set by itself, which can be done in the constructor

Reference link:

Jvm class loader, a detailed explanation of the class loading mechanism, just read this one

In-depth understanding of Java class loader (ClassLoader)

Know almost-class loader interview questions

Guess you like

Origin blog.csdn.net/Candyys/article/details/107025266