Comprehensive analysis of high-level core knowledge in Java-class loader (parent delegation model, source code analysis. Custom class loader!)

One, review the class loading process

Class loading process: loading -> connection -> initialization. The connection process can be divided into three steps: verification -> preparation -> analysis.

The loading phase of a non-array class ( the action of obtaining the binary byte stream of the class during the loading phase ) is the most controllable phase. We can complete this step and customize the class loader to control the way the byte stream is obtained. ( Override the loadClass() method of a class loader ). The array type is not created by the class loader, it is created directly by the Java virtual machine.

All classes are loaded by the class loader, and the function of loading is to load the .class file into memory.

Two, class loader summary

Three important ones are built into the JVM ClassLoader, except that BootstrapClassLoaderother class loaders are implemented by Java and all inherited from java.lang.ClassLoader:

  1. BootstrapClassLoader (boot class loader) : top-level class loading, realized by C ++, is responsible for loading %JAVA_HOME%/libjar package and class or directory, or -Xbootclasspathall of the parameters specified in the class path.
  2. ExtensionClassLoader (extension class loader) : primarily responsible for loading the directory %JRE_HOME%/lib/extjar package and class directory, or java.ext.dirsjar package under system variables specified path.
  3. AppClassLoader (application class loader) : A loader for our users, responsible for loading all jar packages and classes under the current application classpath.

Reference: "Comprehensive Analysis of Java Intermediate and Advanced Core Knowledge"
Students who want to obtain this learning material can click here to obtain it for free """"""""""""""""

Three, the parent delegation model

1. Introduction to the Parental Delegation Model

Each class has a corresponding class loader. The system ClassLoderuses the parental delegation model by default when working together . That is, when the class is loaded, the system will first determine whether the current class has been loaded. The loaded class will return directly, otherwise it will try to load. When loading, the request will be delegated to the parent class loader first loadClass(), so all requests should eventually be transmitted to the top-level startup class loader BootstrapClassLoader. When the parent class loader cannot handle it, it is up to itself to handle it. When the parent class loader is null, the startup class loader will be used BootstrapClassLoaderas the parent class loader.

Each class loading has a parent class loader, we verify through the following program.

public class ClassLoaderDemo {
    
     
	public static void main(String[] args) {
    
     
		System.out.println("ClassLodarDemo's ClassLoader is " + 
ClassLoaderDemo.class.getClassLoader()); 
		System.out.println("The Parent of ClassLodarDemo's ClassLoader is " + 
ClassLoaderDemo.class.getClassLoader().getParent()); 
		System.out.println("The GrandParent of ClassLodarDemo's ClassLoader is " + 
ClassLoaderDemo.class.getClassLoader().getParent().getParent()); 
	} 
}

Output

ClassLodarDemo's ClassLoader is sun.misc.Launcher$AppClassLoader@18b4aac2 
The Parent of ClassLodarDemo's ClassLoader is 
sun.misc.Launcher$ExtClassLoader@1b6d3586 
The GrandParent of ClassLodarDemo's ClassLoader is null

AppClassLoaderThe parent class loader as ExtClassLoader
ExtClassLoaderparent class loader is null, null does not mean that ExtClassLoader no parent class loader , butBootstrapClassLoader .

In fact, the translation of this parent is easy for others to misunderstand. We generally understand that both parents are parents. The parents here are more people of the "parent generation", not that there is really a Mother ClassLoader and a Father ClassLoader. In addition, the "parent-child" relationship between class loaders is not reflected through inheritance, but is determined by "priority". The official API documentation describes this part as follows:

The Java platform uses a delegation model for loading classes. The basic idea is that everyclass loader has a “parent” class loader. When loading a class, a class loader first"delegates" the search for the class to its parent class loader before attempting to find theclass itself.

2. The parent delegation model realizes source code analysis

Parent delegation model implementation code is very simple, very clear logic, are concentrated in java.lang.ClassLoaderthe loadClass(), the relevant code is shown below.

private final ClassLoader parent; 
protected Class<?> loadClass(String name, boolean resolve) 
		throws ClassNotFoundException 
	{
    
     
		synchronized (getClassLoadingLock(name)) {
    
     
			// 首先,检查请求的类是否已经被加载过 
			Class<?> c = findLoadedClass(name); 
			if (c == null) {
    
     
				long t0 = System.nanoTime(); 
				try {
    
    
					if (parent != null) {
    
    //父加载器不为空,调用父加载器loadClass()方法处理 
						c = parent.loadClass(name, false); 
					} else {
    
    //父加载器为空,使用启动类加载器 BootstrapClassLoader加载 
						c = findBootstrapClassOrNull(name); 
					} 
				} catch (ClassNotFoundException e) {
    
     
					//抛出异常说明父类加载器无法完成加载请求 
				}
				
				if (c == null) {
    
     
					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; 
	} 
}

3. The benefits of the parent delegation model

The parental delegation model ensures the stable operation of Java programs and avoids repeated loading of classes (the way JVM distinguishes different classes is not only based on the class name, but the same class file is loaded by different class loaders to produce two different classes) , It also ensures that the core API of Java is not tampered with. If no parent delegation model, but each class loader to load their own words will be some problems, such as we are called to write a java.lang.Objectclass, then when the program is running, the system will appear a number of different Objectclasses.

4. What if we don't want to use the parental delegation model?

In order to avoid parents entrust mechanism, we can define its own class loader, then rewrite loadClass()can be.

Four, custom class loader

Except for BootstrapClassLoaderother class loaders, they are implemented by Java and all inherited from it java.lang.ClassLoader. If we want to customize our own class loader, we obviously need to inherit ClassLoader.


Reference materials: "Comprehensive Analysis of Java Intermediate and Advanced Core Knowledge"
Students who want to obtain this learning material can click here to obtain it for free "" "" "" "" "" ""

Guess you like

Origin blog.csdn.net/Java_Caiyo/article/details/111301247