• I doubt
  • ClassLoader and delegate model
    • This system
    • Load delegate analysis
    • Question answer
  • Technical principle of hot loading
  • How does ClassLoader implement dynamic jar loading and plug-in mode system?
  • Added title


Recently, I read xu Lingbo’s in-depth analysis of the Inside of Java Web technology, and I answered some questions I have had since LEARNING Java, so I wrote them down.

I doubt#

  1. What is the parent delegation model (actually a translation error, parent delegation, just a parent delegation model)? How to do that? Why is this implemented?
  2. What is the technical principle of hot loading?
  3. How does ClassLoader implement dynamic jar loading and plug-in mode system? Follow this tutorial to find the answers.

ClassLoader and delegate model#

This system#

As the name suggests, classloaders are classloaders (specifically, abstract superclasses of JVM platform classloaders) that load classes into the JVM using a loading strategy called the parent delegate model. Its main method is as follows

  1. DefineClass is responsible for parsing the class file and byte stream into a class object that the JVM can recognize. This means that the object can be instantiated as long as the corresponding class stream is available. Note that the class object must be resolved before it can be used
  2. The method of overwriting findClass custom rules, usually used with defineClass, is to find a class file and then parse it to generate a class object.
  3. LoadClass the call to the JVM loading method, this method can be in findLoadedClass, loadClass didn’t find call findClass (String) looking for a Class object, and then decide whether to link according to the resolve of the flag.
  4. ResolveClass links to a Class object, which can only be used after this operation

The JVM platform provides three classLoaders:

  • Bootstrap ClassLoader is a ClassLoader implemented by C++ that does not belong to the JVM platform and is controlled by the JVM itself. It mainly loads classes required by the JVM. When the parent of the ClassLoader is null, Bootstrap is used The ClassLoader is loaded, and it no longer plays a role in the parent delegate model.
  • ExtClassLoader is a class loader instantiated by the JVM in sun.misc.Launcher that loads files in the corresponding directory of System.getProperty(” java.ext.dirs “). It is also an AppClass The parent class Loader
  • AppClassLoader, created by ExtClassLoader for parent, is also an internal class of Sun.misc.Launcher, which loads classes in System.getProperty(” java.class.path “) The classpath you often use includes the path to the current application and jRE-related JAR packages.

It is notBootstrap ClassLoaderThe JVM architecture’s ClassLoader structure is as follows



ClassLoader is a Decorator in the Decorator mode. AppClassLoader is essentially an enhanced version of ExtClassLoader

1

Launcher.AppClassLoader.getAppClassLoader(Launcher.ExtClassLoader.getExtClassLoader())

Is it similar to IO initialization? Parental delegation, as I understand it, is essentially an application of the decorator pattern, using composition instead of inheritance except that the decorator is called parent, and the idea is the same but the usage is different. If you want to implement your own ClassLoader, just inherit java.net.URLClassLoader and customize the loading logic.

Load delegate analysis#

Next, focus on the loadClass() method, which is the core method for loading the class binaries.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

protected Class<? > loadClass(String name, boolean resolve) throws ClassNotFoundException

{

synchronized (getClassLoadingLock(name)) {

// First, check if the class has already been loaded

Class<? > c = findLoadedClass(name);

if (c == null) {

long t0 = System.nanoTime();

try {

// BootStrapClassLoader will be used as the parent class when the parent loader does not exist

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 is null, the parent loader is not loaded, and the subclass’s own loading strategy ‘findClass()’ method is used

if (c == null) {

// If still not found, then invoke findClass in order

// to find the class.

long t1 = System.nanoTime();

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;

}

}

Call java.lang.ClassLoader#findBootstrapClass when the parent class does not exist and use BootStrapClass to load. This method is a native method and further demonstrates Bootstrap The Classloader has no parent class relationship to the JVM’s Classloader. Completely independent.

Question answer#

So start answering the question 1. What is the parental delegation model? BootStrapClassLoader does not exist -> It is important to note that BootStrapClassLoader is an internal JVM loading tool implemented by C++. It has no corresponding Java objects and therefore does not belong to this delegation system. Classloader is essentially an application of the decorator pattern composition idea.

So what are parents?This is just a translation problem if you look at the ClassLoader comments. Parent -> parentThe decorator pattern is a single-class enhanced delegate.

RednaxelaFX confirms this

2. How is the delegation model implemented? Please refer to my article on design Patterns design Patterns decorator Patterns thinking

3. Why use the delegation model? To answer this question, we need to know how Java determines that two classes are the same class. In the following paragraph, the official statement states that two objects are equivalent if the full class name (including the package name) is the same and their classloader is the same.

1

2

3

At run time, several reference types with the same binary name may be loaded simultaneously by different class loaders.

These types may or may not represent the same type declaration.

Even if two such types do represent the same type declaration, they are considered distinct.

For the Object class, because the parent loader loads first, it can ensure that the corresponding Object of all Object subclasses are loaded by the same ClassLoader, which ensures that the objects are equal. To put it simply, the delegate class-priority mode ensures the loader’s priority, allowing the ClassLoader with the highest priority to load first and the lower priority to take the turn.

Technical principle of hot loading#

Hot deployment is extremely useful during development, and tools such as Jrebel can greatly save application debugging time. About thermal loading technology can refer to www.hollischuang.com/archives/60… The findLoadedClass() method detects that the class has been loaded and does not load the class again. The essence of hot loading is to replace the loaded class.

In Spring the Boot Devtools uses two classLoaders, a custom ClassLoader for classes written by developers, and a default loader for third-party packages, so whenever code changes need to be hot loaded, the custom ClassLoader is discarded Then re-use it to load, so that hot deployment is achieved.

Jrebel uses what appears to be a bytecode approach to modifying classes, so I won’t discuss the specifics.

For Tomcat, the technology of hot deployment is every time before cleaning up references, and then create a new ClassLoaderWebClassLoader to reload the application, the load makes objects in the permanent generation increased, so cleaning is full GC, this is not controlled, so it caused the Tomcat frequent hot deployment will trigger the Java. Lang. OutOfMemoryErrorPermGen space this bug.

How does ClassLoader implement dynamic jar loading and plug-in mode system?#

The delegate model of the ClassLoader makes it easy to extend custom classloaders, so the basic steps are to define your own ClassLoader -> load the specified JAR -> create the required application instance, roughly as follows.

1

2

3

4

5

6

7

8

9

10

String jarPath = “/ Users/niuli/workspace/quding – git/quding – study/helloworld/target/hello world – 1.0 – the SNAPSHOT. Jar”;

URL jarUrl = new File(jarPath).toURI().toURL();

// Load the jar

URLClassLoader loader = new URLClassLoader(new URL[]{jarUrl},Thread.currentThread().getContextClassLoader());

// Get the plug-in Class object

Class helloClass = loader.loadClass(“com.itoolshub.hello.HelloWorld”);

// Create the object

IHelloWorldService helloWorldService = (IHelloWorldService) helloClass.newInstance();

// Call the method

helloWorldService.sayHello();

In addition, the plugin mode usually has some configuration file plugin.xml, which tells the system what the main external service classes are and some default configurations. But the idea is pretty much the same.

If a class is loaded in the permanent generation, then the full GC will clean up classes that are not strongly referenced in the permanent generation.

  1. All instances of this class are already GC.
  2. The ClassLoader instance that loaded the class has already been GC.
  3. The java.lang.Class object of this Class is not referenced anywhere.

Added title#

In the parent delegate model, from top to bottom, what class loaders are there and what classes are loaded? Bootstrap ClassLoader: classes required by the JVM to attempt to load an ExtClassLoader when parent in the ClassLoader is null: Java.ext. dirs AppClassLoader; It mainly loads classes under java.class.path, including user-defined classes that correct the parent delegate model, which is essentially the decorator pattern application.

The parent delegate model is a model released by JDK1.2. Before this, developers overwrite the loadClass() method to implement custom load logic. This method is the key algorithm of the parent delegate model, so overwrite the model completely

1

2

3

4

public static <S> ServiceLoader<S> load(Class<S> service) {

ClassLoader cl = Thread.currentThread().getContextClassLoader();

return ServiceLoader.load(service, cl);

}

The SPI mechanism is loaded using a Thread context ClassLoader, which inherits one from the parent Thread if it is not set, or AppClassLoader if it is not set in the global scope of the application. This process is actually handled by the parent class requesting a subclass. 3. Hot deployment, hot loading techniques, etc. break the parental delegation model.

QuDing ‘s Blog
Mrdear. Cn / 2017/11/13 /…
Java Learning Record – Four references in Java
Git rollback operations