first, what is the load of a class
Class loading refers to reading the binary data in the class's. class file into memory, placing it in the method area of the run-time data area, and then creating a Java.lang.Class object in the heap that encapsulates the data structure of the class within the method area. The final product loaded by the class is a class object located in the heap, which encapsulates the data structure of the class within the method area, and provides the Java programmer with an interface to access the data structures within the method area.
The ClassLoader does not need to wait until a class is "first active" and then load it, and the JVM specification allows the ClassLoader to preload it when it is expected that a class will be used. If you encounter a missing or an error in a. class file during pre-loading, the ClassLoader must report an error (Linkageerror error) when the program first actively uses the class, and the class loader will not report an error if the class has not been actively used by the program
How to load A. class file
– Load directly from the local system
– Download. class files over the network
– Loading. class files from archive files such as Zip,jar
– Extract the. class file from the proprietary database
– Dynamically compile the Java source file into a. class file
Ii. Life cycle of classes
The process of loading, validating, preparing, parsing, and initializing five stages of the class load. In these five phases, the order in which the four phases of loading, validating, preparing, and initializing occurs is deterministic, and the parsing phase is not necessarily, which in some cases can begin after the initialization phase, in order to support runtime bindings for the Java language (also become dynamic or late bound). Also note that the stages here are started in order, rather than sequentially or in order, because these phases are usually mixed in a cross-section, often invoking or activating another phase during one phase of execution.
1. Loading: Finding and loading binary data for a class
During the first stage of the load-time class loading process, the virtual machine needs to complete the following three things during the load phase:
1.1、通过一个类的全限定名来获取其定义的二进制字节流。1.2、将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。1.3、在Java堆中生成一个代表这个类的java.lang.Class对象,作为对方法区中这些数据的访问入口。相对于类加载的其他阶段而言,加载阶段(准确地说,是加载阶段获取类的二进制字节流的动作)是可控性最强的阶段,因为开发人员既可以使用系统提供的类加载器来完成加载,也可以自定义自己的类加载器来完成加载。加载阶段完成后,虚拟机外部的 二进制字节流就按照虚拟机所需的格式存储在方法区之中,而且在Java堆中也创建一个java.lang.Class类的对象,这样便可以通过该对象访问方法区中的这些数据。
2. Connection
– Validation: Ensure that the class being loaded is correct
Validation is the first step in the connection phase, which is designed to ensure that the information contained in the byte stream of a class file conforms to the requirements of the current virtual machine and does not compromise the security of the virtual machine itself. The validation phase will roughly complete the 4-phase inspection action:
File Format verification: Verify that the byte stream conforms to the specification of the class file format, for example: whether to start with 0xCAFEBABE, whether the major and minor version numbers are within the processing range of the current virtual machine, and whether the constants in the constant pool have unsupported types.
Meta-data validation: Semantic analysis of the information described in bytecode (note: Comparing the semantic analysis of the JAVAC compilation phase) to ensure that the information it describes conforms to the requirements of the Java language specification, for example: Whether this class has a parent class, except Java.lang.Object.
Bytecode verification: Through data flow and control flow analysis, it is reasonable to determine that the program semantics are legal and logical.
Symbol Reference Validation: Ensures that parsing actions are performed correctly.
The validation phase is important, but not necessary, and it has no effect on the program runtime, and if the referenced classes are repeatedly validated, consider using the-xverifynone parameter to turn off most of the class validation measures to shorten the load time of the virtual machine class.
3. Prepare: Allocate memory for static variables of the class and initialize them to default values
The prep phase is a phase that formally allocates memory for class variables and sets the initial value of class variables, which are allocated in the method area. There are a few things to note about this phase:
1.1、这时候进行内存分配的仅包括类变量(static),而不包括实例变量,实例变量会在对象实例化时随着对象一块分配在Java堆中。1.2、这里所设置的初始值通常情况下是数据类型默认的零值(如0、0L、null、false等),而不是被在Java代码中被显式地赋予的值。
Suppose a class variable is defined as: public static int value = 3;
Then the initial value of the variable value after the prep phase is 0, not 3, because no Java method has started executing, and the putstatic instruction that assigns value 3 is stored in the class constructor () method after the program is compiled, So an action that assigns value to 3 will not be executed until the initialization stage.
· Here are a few more points to note:
· For basic data types, for class variables (static) and global variables, which are used directly if they are not explicitly assigned to them, the system assigns them a default value of 0, and for local variables, they must be explicitly assigned before they are used, otherwise the compilation does not pass.
· Constants that are both static and final modified must be explicitly assigned at the time of declaration, or not at compile time, whereas only final-modified constants can be explicitly assigned at the time of declaration, or they can be explicitly assigned when the class is initialized, in summary, You must assign a value to it explicitly before you use it, and the system does not give it a default value of 0.
· For reference data type reference, such as an array reference, an object reference, and so on, if it is not explicitly assigned and is used directly, the system assigns it a default value of 0, or null.
· If no values are assigned to elements in the array at initialization, the elements will be given a default value of 0 based on the corresponding data type.
1.3、如果类字段的字段属性表中存在ConstantValue属性,即同时被final和static修饰,那么在准备阶段变量value就会被初始化为ConstValue属性所指定的值。
Assume that the above class variable value is defined as: public static final int value = 3;
Compile-time Javac will generate the Constantvalue property for value, and in the prepare phase the virtual machine will assign value to 3 based on the settings of Constantvalue. This is the case when you recall the 2nd example of a passive reference to an object in the previous blog post. We can understand that the static final constant puts its result in the constant pool of the class that called it at compile time
3. Parsing: Converting a symbolic reference in a class to a direct reference
The parsing phase is the process by which a virtual machine replaces a symbolic reference within a constant pool with a direct reference, and the parsing action is primarily for a class or interface, a field, a class method, an interface method, a method type, a method handle, and a call Point qualifier 7 class symbol reference. A symbolic reference is a set of symbols that describe a target, which can be any literal.
A direct reference is a pointer directly to the target, a relative offset, or a handle that is indirectly anchored to the target.
4. Initialization
initialization, which assigns the correct initial value to the static variables of the class, the JVM is responsible for initializing the class, primarily initializing the class variables. There are two ways to set the initial value of a class variable in Java:
① declares that a class variable is a specified initial value
② specifying an initial value for a class variable using a static code block
JVM initialization steps
1.1. If the class has not been loaded and connected, the program loads and connects the class first
1.2, if the immediate parent class of the class has not been initialized, first initialize its immediate parent class
1.3, if the class has initialization statements, then the system executes these initialization statements in turn
Class initialization time: The class is initialized only when the class is actively used, and the active use of the class includes the following six types:
– Create an instance of the class, that is, the new way
– Access a static variable for a class or interface, or assign a value to the static variable
– Call the static method of the class
– Reflections (e.g. Class.forName ("Com.shengsiyuan.Test"))
– Initializes a subclass of a class, and its parent class is also initialized
–java a Class (Java Test) that is marked as the startup class when the virtual machine is started, and runs a main class directly using the Java.exe command
4. End of life cycle
? In the following scenarios, the Java Virtual machine will end the life cycle
– The System.exit () method was executed
– End of normal execution of the program
– the program encountered an exception or error during execution and terminated abnormally
– the Java Virtual machine process terminates due to an operating system error
Third, class loader
Looking for the ClassLoader, let's start with a small example
Package com.neo.classloader;
public class Classloadertest {
public static void Main (string[] args) {
ClassLoader loader = Thread.CurrentThread (). Getcontextclassloader ();
SYSTEM.OUT.PRINTLN (loader);
System.out.println (Loader.getparent ());
System.out.println (Loader.getparent (). GetParent ());
}
}
After running, the output results:
Sun.misc.Launcher APPC LassLoad eR@ -F eF -asuN.mIsC.LauNCheR [Email protected]
Null
As can be seen from the above results, it is not obtained to Extclassloader's parent Loader, because Bootstrap Loader (boot class loader) is implemented in C language, cannot find a definite way to return the parent Loader, then returns NULL.
The hierarchical relationships of these kinds of loaders are as follows:
Note: The parent loader is not implemented by inheritance, but by combining it.
From the point of view of a Java virtual machine, there are only two different classloader: Start the ClassLoader: it uses C + + implementations (this is limited to hotspots, That is, the default virtual machine after JDK1.5, there are many other virtual machines are implemented in the Java language, is a part of the virtual machine itself; all other ClassLoader: These classloader are implemented by the Java language, independent of the virtual machine, and all inherit from the abstract class Java.lang.ClassLoader, which The class loader needs to be loaded into memory by the startup ClassLoader before it can load other classes.
From the Java Developer's point of view, the class loader can be roughly divided into the following three categories:
Start the ClassLoader: Bootstrap ClassLoader, which is responsible for loading the jdk\jre\lib (the JDK represents the JDK's installation directory, the same below), or the path specified by the-xbootclasspath parameter, and class libraries that can be recognized by the virtual machine (such as Rt.jar, all classes beginning with java.* are bootstrap ClassLoader loaded). The startup ClassLoader cannot be referenced directly by a Java program.
Extension class loader: Extension ClassLoader, which is implemented by Sun.misc.launcher$extclassloader, is responsible for loading the Dk\jre\lib\ext directory, or all class libraries in the path specified by the JAVA.EXT.DIRS system variable (such as classes beginning with javax.*), developers can use the extension class loader directly.
Application ClassLoader: Application ClassLoader, which is implemented by Sun.misc.launcher$appclassloader, is responsible for loading the class specified by the user class path (ClassPath). Developers can use the ClassLoader directly, if the application does not customize its own classloader, typically this is the default class loader in the program.
Applications are loaded with each other by these three kinds of loaders, and if necessary, we can also add a custom class loader. Because the JVM's own ClassLoader only knows how to load the standard Java class file from the local file system, if you write your own classloader, you can do the following:
1) The digital signature is automatically validated before the non-confidence code is executed.
2) dynamically create custom build classes that meet user-specific needs.
3) Obtain Java class from a specific location, such as in a database and in a network.
JVM class loading mechanism
? Overall, when a classloader is responsible for loading a class, other classes that the class relies on and references will also be loaded by the ClassLoader, unless the display uses a different classloader to load
The parent class delegate, which lets the parent ClassLoader attempt to load the class, attempts to load the class from its own classpath only if the parent class loader cannot load the class
Caching mechanism, the caching mechanism will ensure that all the loaded class will be cached, when the program needs to use a class, the class loader first look for the class from the buffer, only the buffer does not exist, the system will read the corresponding binary data, and convert it to a class object, Deposit buffer. This is why the JVM must be restarted after the class has been modified, and the program's modifications will not take effect
Iv. Loading of classes
There are three ways to load a class:
1. When the command line starts the application, it is loaded by the JVM initialization
2. Dynamic loading via Class.forName () method
3. Dynamic loading via Classloader.loadclass () method
Class.forName () and classloader.loadclass () differences
Class.forName (): Loads the class's. class file into the JVM, also interprets the class, and executes the static block in the class;
Classloader.loadclass (): The only thing to do is to load the. class file into the JVM, not to execute the contents of static, only to execute the static block in Newinstance.
Note:
Class.forName (name, initialize, loader) with the parameter function also controls whether static blocks are loaded. And only call the Newinstance () method using the call constructor to create the class object.
Five, parental assignment model
The workflow of the parent delegation model is that if a classloader receives a request for a class load, it does not attempt to load the class on its own, but instead delegates the request to the parent loader to complete, then up, so that all class load requests should eventually be passed to the top-level startup class loader. The load cannot be completed until the parent loader finds the required class in its search scope, and the child loader tries to load the class on its own.
Parent delegation Mechanism:
1. When Appclassloader loads a class, it first does not attempt to load the class itself, but instead delegates the class load request to the parent ClassLoader Extclassloader to complete.
2. When Extclassloader loads a class, it does not attempt to load the class on its own, but instead delegates the class load request to Bootstrapclassloader to complete.
3, if the Bootstrapclassloader load failure (for example, in $java_home/jre/lib not found in the class), will use the Extclassloader to try to load;
4, if the Extclassloader also failed to load, the Appclassloader will be used to load, if the Appclassloader also failed to load, will report an exception classnotfoundexception.
Vi. Custom Class Loaders
通常情况下,我们都是直接使用系统类加载器。但是,有的时候,我们也需要自定义类加载器。比如应用是通过网络来传输 Java 类的字节码,为保证安全性,这些字节码经过了加密处理,这时系统类加载器就无法对其进行加载,这样则需要自定义类加载器来实现。自定义类加载器一般都是继承自 ClassLoader 类,从上面对 loadClass 方法来分析来看,我们只需要重写 findClass 方法即可。
Loading mechanism for Java classes