Parent delegation model to talk about the destruction of the fourth - Modular

Foreword

JDK9 introduced a modular system Java (Java Platform Module System) package to achieve isolation mechanism can be configured, while the JVM class loading architecture also made an adjustment, which is the parent delegation model Fourth damage. The first three were destroyed: the model before the launch, SPI mechanisms, as well as hot-swap mechanism OSGI appointed as the representative of the parents, not elaborate here.

Parent delegation model

Brief introduction

Prior to the introduction of JDK9, most Java program will be loaded with the following three class loader

  • Start class loader (Bootstrap Class Loader): written by C ++, is responsible for loading <JAVA_HOME> \ jre \ lib directory under the category of, for example, the most basic of Object, Integer, which exists in the file rt.jar classes, these classes are generally Java is the cornerstone of the program.
  • Extension class loader (Extension Class Loader): responsible for loading the <JAVA_HOME> \ jre \ lib directory under the category ext \, before we can JDK9 universal library in JAVA ext directory to extend the functionality, but the actual projects are dependent jar package introduced by maven. And JDK9 canceled the class loader, replaced by a class loader platform (Platform Class Loader), the following will be their introduction.
  • Application class loader (Application Class Loader): responsible for loading class at ClassPath path, most engineers are usually written classes are loaded by the class loader.

Work order

Explanation

If a request is received ClassLoader class loading, he will first request will be first delegate to the parent class loader is complete, only the parent class loader can not load the sub-loader will finish loading.

Parent delegation model

Source

The following code holding the core logic, and added comments, mainly two steps

  1. If the parent class is not loaded with the empty parent class loader
  2. Parent class loader loads itself unsuccessful reload
            Class<?> c = findLoadedClass(name);
            //如果该类没加载过
            if (c == null) {
                try {
                //如果有父类加载器
                    if (parent != null) {
                    //使用父类加载器加载
                        c = parent.loadClass(name, false);
                        ...
                    } 
                } 
                   if (c == null) {
                    ...
                    //父类加载器没有加载成功则调用自身的findClass进行加载
                    c = findClass(name);
										...
                }
            }
       

It is noteworthy that the parent-child relationship is not inherited Here's parent, but the parent-child relationship of the combination, only one parameter parent class loader.

Icon

If you think the above explanation may look relatively more abstract image of the illustration below, where the enemy is, we want to load the jar package

Work order

Shortcoming

Through the above comic self-evident, when the real enemy came by this inefficient convey mechanism, how could hit a home run it?

  • Start class loader is responsible for loading <JAVA_HOME> \ jre \ lib directory
  • Extension class loader is responsible for loading <JAVA_HOME> \ jre \ lib \ ext directory
  • Application class loader is responsible for loading ClassPath directory.

Since everything their duties, why can not load the class time step it?

By analyzing JDK9 class loader source code, I found the latest class loader structure to some extent alleviated this situation

Modular JDK

Before JDK9, JVM base class rt.jar had previously been in this package, this package is the cornerstone of running JRE. This is not only a violation of the principle of single responsibility, the same procedure will be a lot of useless class also packaged together at compile time, resulting in bloated.

In JDK9, full JDK are constructed based on a modular, previous rt.jar, tool.jar split into dozens of modules, the actual translation of the module is only used to compile, while each of its divisions class loader post, only load the module responsible for their own.

moudle

Modular Load Source

  Class<?> c = findLoadedClass(cn);
      if (c == null) {
         // 找到当前类属于哪个模块
         LoadedModule loadedModule = findLoadedModule(cn);
         if (loadedModule != null) {
            //获取当前模块的类加载器
            BuiltinClassLoader loader = loadedModule.loader();
            //进行类加载
            c = findClassInModuleOrNull(loadedModule, cn);
         } else {
            // 找不到模块信息才会进行双亲委派
         if (parent != null) {
           c = parent.loadClassOrNull(cn);
         }
       }

The above code is the destruction of the parent delegation model "irrefutable evidence", and when we continue to follow up findLoadedModule, will find the corresponding module is to find the path name, and maintenance is below this Map of the data structure.

Map<String, LoadedModule> packageToModule
        = new ConcurrentHashMap<>(1024);

LoadedModule which not only can see information about the loader module, and the module for describing dependence, mref exposed outside the module information, to achieve a modular LoadedModule is important to realize package isolation mechanism.

moduleMap

Each module has a message BuiltinClassloader, this class has three subclasses, we analyze their parent-child relationship by source

image-20200329162147803

ClassLoaders class can be found in, PlatformClassLoader the parent is BootClassLoader, whereas the parent is AppClassLoader PlatformClassLoader.

public class ClassLoaders {

    // the built-in class loaders
    private static final BootClassLoader BOOT_LOADER;
    private static final PlatformClassLoader PLATFORM_LOADER;
    private static final AppClassLoader APP_LOADER;

    static {
        BOOT_LOADER =
            new BootClassLoader((append != null && !append.isEmpty())
                ? new URLClassPath(append, true)
                : null);
                
        PLATFORM_LOADER = new PlatformClassLoader(BOOT_LOADER);
        ...
        APP_LOADER = new AppClassLoader(PLATFORM_LOADER, ucp);
    }
  }

in conclusion

  1. After destruction of the parent delegation model more efficient, reducing the number of unnecessary between class loader operation delegation
  2. JDK9 modular Java program can reduce the volume of packaging, while the separation line and with better encapsulation
  3. Each module has a dedicated class loader program on concurrency will be better

Guess you like

Origin www.cnblogs.com/yangkw/p/12615114.html