JVM class loader, detailed explanation of class loading mechanism, look here! !

Preface

Today we will talk about the process of class loading in jvm. We have written so many classes but don't know the process of class loading. Isn't it awkward?

The startup of jvm is accomplished by creating an initial class by the bootstrap class loader, which is specified by the specific implementation of jvm. [From official specifications]

One of the JVM components is the class loader subsystem, we will talk about this component in detail today.

Java code execution flow chart

Through this flow chart, everyone understands how the Java code we wrote is executed, which involves going through the process of the class loader, so let's talk about the knowledge points in it carefully.

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

Class loading subsystem

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

Class loading system architecture diagram

It’s okay if you don’t understand these two pictures for the time being, follow me and look down

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

Class life cycle

The life cycle of a class includes: loading, linking, initialization, use, and unloading. Loading, linking, and initialization belong to the process of class loading, and we will explain it in detail below. Use refers to the use of our new object, and unload refers to the object being garbage collected.

The process of class loading

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

  • The first step: Loading loading

Get the .class of the class by its fully qualified name (package name + class name)

File binary byte stream

Convert the static storage structure represented by the binary byte stream into the data structure of the method area at runtime

Generate a java.lang.Class object representing the class in the memory as the access entry for various data of this class in the method area

Summary: Load binary data into memory —> Map it into a structure that JVM can recognize —> Generate class files in memory.

  • Step 2: Linking

Linking refers to the process of merging the class created above into the Java virtual machine so that it can be executed. It can be divided into three stages: verification, preparation, and analysis.

① Verify (Verify)

Ensure that the information contained in the byte stream in the class file meets the requirements of the current virtual machine, and ensure the correctness of the loaded class without endangering the security of the virtual machine.

② Preparation (Prepare)

Allocate memory for the static field in the class and set the default initial value, for example, the initial value of the int type is 0. The static field modified by final will not be set because final is allocated at compile time

③ Resolve

The purpose of the parsing phase is to convert the symbolic references in the constant pool into direct references (resolving the symbolic references in the constant pool into actual references). If the symbol reference points to an unloaded class, or a field or method of an unloaded class, then the resolution will trigger the loading of this class (but not necessarily the linking and initialization of this class.)

In fact, parser operations are often accompanied by JVM execution after initialization. Symbol reference is a set of symbols to describe the referenced target. The literal form of symbol reference is clearly defined in the Class file format of the "Java Virtual Machine Specification". A direct reference is a pointer that directly points to the target, a relative offset, or a handle that is indirectly located to the target.

The parsing action mainly targets classes, interfaces, fields, class methods, interface methods, method types, etc. Corresponding to CONSTANT_Class_info, CONSTANT_Fieldref_info, CONSTANT_Methodref_info, etc. in the constant pool.

  • The third step: initialization

Initialization is to execute the constructor method init of the class

()the process of.

This method does not need to be defined, it is a combination of the assignment actions of all class variables in the javac compiler automatically collected and the statements in the static code block.

If the class has a parent class, jvm will ensure that the init of the parent class is executed first, and then the init of the subclass is executed.

Classification of class loaders

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

  • The first one: startup class/boot class: Bootstrap ClassLoader

This class loader is implemented in C/C++ language and is nested inside the JVM. Java programs cannot directly manipulate this class.

It is used to load Java core class libraries, such as: JAVA_HOME/jre/lib/rt.jar, resources.jar, sun.boot.class.path packages under the path, used to provide packages required for jvm operation.

It is not inherited from java.lang.ClassLoader, it has no parent class loader

It loads the extension class loader and the application class loader and becomes their parent class loader

For security reasons, the startup class only loads classes starting with the package name: java, javax, sun

  • Second: Extension ClassLoader: Extension ClassLoader

Written in Java language, implemented by sun.misc.Launcher$ExtClassLoader, we can use Java programs to operate this loader

Derived and inherited from java.lang.ClassLoader, the parent class loader is the startup class loader

Load the class library from the system property: java.ext.dirs directory, or load the class library from the JDK installation directory: jre/lib/ext directory. We can put our own package in the above directory and it will be loaded automatically.

  • Third: Application Classloader: Application Classloader

Written in Java language, by sun.misc.Launcher$AppClassLoader

achieve.

Derived and inherited from java.lang.ClassLoader, the parent class loader is the startup class loader

It is responsible for loading the class library under the path specified by the environment variable classpath or the system property java.class.path

It is the default class loader in the program, and the classes in our Java program are all loaded by it.

We can get and operate this loader through ClassLoader#getSystemClassLoader()

  • Fourth: Custom Loader

Under normal circumstances, the above three loaders can satisfy our daily development work. When not satisfied, we can also customize the loaders

For example, use the network to load Java classes, in order to ensure the security of the transmission, using encryption operations, then the above three loaders can not load this class, this time you need to customize the loader

Custom loader implementation steps

Inherit the java.lang.ClassLoader class and override the findClass() method

If there are no too complicated requirements, you can directly inherit the URLClassLoader class and override the loadClass method. For details, please refer to AppClassLoader and ExtClassLoader.

Several ways to obtain ClassLoader

It is an abstract class, all subsequent class loaders inherit from ClassLoader (not including the startup class loader)

// 方式一:获取当前类的 ClassLoader
clazz.getClassLoader()
// 方式二:获取当前线程上下文的 ClassLoader
Thread.currentThread().getContextClassLoader()
// 方式三:获取系统的 ClassLoader
ClassLoader.getSystemClassLoader()
// 方式四:获取调用者的 ClassLoader
DriverManager.getCallerClassLoader()

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 file into memory to generate class objects.

When loading the class, the parent delegation mechanism is adopted, that is, a task delegation mode that hands the request to the parent class for processing.

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

  • working principle

(1) If a class loader receives a class loading request, it will not load it first, and will delegate the request to the parent class loader to execute it.

(2) If the parent class still has a parent class loader, continue to delegate upwards until the startup class loader: Bootstrap ClassLoader

(3) If the parent class loader can complete the loading task, it will return a successful result. If the parent class fails to load, the child class will try to load it. If the child class fails to load, it will throw a ClassNotFoundException exception. This is the parental delegation mode

  • Third-party package loading method: reverse delegation mechanism

There are many Service Provider Interfaces (SPI) in Java applications. These interfaces allow third parties to provide implementations for them. For example, common SPIs include JDBC, JNDI, etc. These SPI interfaces belong to the Java core library and generally exist. In the rt.jar package, it is loaded by the Bootstrap class loader. The Bootstrap class loader cannot directly load the implementation class of SPI. At the same time, due to the existence of the parental delegation mode, the Bootstrap class loader cannot delegate the SPI implementation class of the AppClassLoader loader in reverse. In this case, we need a special class loader to load third-party class libraries, and the thread context class loader (the disruptor of the parent delegation model) is a good choice.

It can be seen from the figure that the rt.jar core package is loaded by the Bootstrap class loader, which contains the SPI core interface classes. Because the classes in SPI often need to call the methods of external implementation classes, jdbc.jar contains external implementation classes (jdbc.jar). (jar exists in the classpath path) cannot be loaded by the Bootstrap class loader, so the thread context class loader can only be delegated to load the implementation classes in jdbc.jar into memory for use by SPI related classes. Obviously this loading method of the thread context class loader destroys the "parental delegation model". It abandons the parental delegation load chain model during execution, so that the program can use the class loader in reverse. Of course, this also makes the Java class loader become More flexible.

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

  • Sandbox security mechanism

Customize the String class, but when loading the custom String class, it will be the first to use the boot class loader to load, and the boot class loader will first load the files that come with the JDK (javalangString in the rt.jar package. class), the error message says that there is no main method because of the String class in the loaded rt.jar package. This can ensure the protection of the Java core source code, which is the sandbox security mechanism.

Guess you like

Origin blog.csdn.net/doubututou/article/details/109249941