We all know that Java virtual machines are used to run our compiled. class file, class file with all kinds of information, virtual confidential run these files, the first thing is to load into the virtual machine, which leads to this summary of the problem-how the virtual machine is loaded with these class files. After loading the virtual machine is how to handle the information entrainment in the file. class loading mechanism
First thing class loading mechanism, it is necessary to introduce the concept first:
The virtual machine loads the description class data from the class file into memory, verifies and transforms the data, resolves and initializes the Java type that can be used directly by the virtual machine, which is the class loading mechanism of the virtual machine. the timing of class loading
The entire lifecycle of a class, from being loaded to a virtual machine to unloading memory, includes loading, validating, preparing, parsing, initializing, using, and uninstalling 7 phases. Its life cycle is as shown in the figure:
The order of the 5 phases of load, verify, prepare, initialize, and unload is OK, the class loading process must begin in this order, and the parsing phase is not necessarily, in order to support runtime binding of the Java language, the parsing action is placed after class initialization. the whole process of class loading Loading
In the load phase, the virtual machine needs to do the following 3 things:
1 to obtain a binary byte stream that defines this class through the fully qualified name of a class.
2) Converts the static storage structure represented by this byte stream into the RUN-TIME data structure of the method area.
3) generates a Java.lang.Class object representing this class in memory as an access point for the various data of this class in the method area.
This is the three point of the virtual machine specification, but it does not specify exactly what to do.
For example, the first: virtual confidential a binary byte throttling, but did not specify where to get from, how to obtain, this can play a lot of tricks to come. The most common is to read from a compressed package, a jar pack, a war package, and so on. There are JSP files directly generated corresponding class classes.
After the load phase is complete, the binary stream of bytes outside the virtual machine is stored in the method area according to the format required by the virtual machine, and the data storage format in the method area is defined by the virtual machine, and the virtual machine specification does not specify the specific data structure of the area. The object of an Java.lang.Class class is then instantiated in memory (not explicitly defined in the Java heap, in the hotspot virtual machine, where the class object is placed in the method area, although it is also an object) validation
Validation is the first step in the connection phase, which is to ensure that the information contained in the byte stream of the class file meets the requirements of the current virtual machine and does not compromise the security of the virtual machine itself.
The validation phase will generally complete the following 4 phases of the inspection action: file format checksum, metadata validation, bytecode verification, symbolic reference verification.
1) file Format verification
To verify that the byte stream conforms to the class file format specification and can be processed by the current version of the virtual machine. This section is the direct operation of the word throttling, through the verification of the word stream into memory after the storage, then the action is based on the method area of the storage structure, no longer directly manipulate the word throttling.
2) meta-data validation
This is done by semantic analysis of the information described by the bytecode to ensure that the information it describes conforms to the requirements of the Java language specification. The semantic checksum of the metadata information of the class, which mainly describes the data, is a kind of data describing the relationship between the code. such as the relationship between child parent classes, etc...
3) Byte code verification
This step is the most complex, the main purpose is through data flow and control flow analysis, to determine the semantics of the program is legitimate and logical. This verifies the method body of the class.
4) Symbolic Reference verification
The final phase of validation occurs when a virtual machine converts a symbolic reference to a direct reference, which occurs during the third phase of the connection ——— parsing phase. Symbolic reference validation can be viewed as a matching checksum for information outside the class itself (the various symbolic references in a constant pool). It is designed to ensure that parsing actions are performed correctly, and if the symbolic references are not validated correctly, a subclass of the Java.lang.IncompatibleClassChangeError exception is thrown, such as a common nosuchmethoderror, Illegalaccesserror. Ready to
The preparation phase is the formal allocation of memory for class variables and the setting of the initial values of class variables, the memory used by these variables to be allocated in the method area. Note that there are only static variables for memory allocations at this stage, not instance variables, and instance variables will be assigned to the Java heap along with objects when the object is instantiated. The initial values set are typically 0 values of the data type, but if the class variable is set to final, the Constantvalue property is generated in the field property sheet at compile time, and the virtual machine is set according to Constantvalue in the prep phase. parsing
The parsing phase is the process by which a virtual machine replaces a symbolic reference of a constant pool with a direct reference.
Symbolic reference: A symbolic reference is a set of symbols that describe the target that is referenced, and the symbol can be any form of literal, as long as the object can be positioned without ambiguity when used.
Direct reference: A pointer to a target, a relative offset, or a handle that can be directed directly to the target.
The parsing action is mainly for class or interface, field, class method, interface method, method type, method handle and call Point Qualifier 7 class symbol reference, corresponding to Constant_class_info, Constant_fieldref_info, CONSTANT of constant pool respectively. _methodred_info, Constant_interfacemethodref_info, Constant_methodtype_info, Constant_methodhandle_info and Constant_ Invokedynamic_info7 the type of constant.
1 parsing of class or interface
Suppose you have Class D, if you want to parse a symbol to refer to n as a direct reference to class or interface C:
If C is not an array type, the virtual opportunity passes the fully qualified name representing N to the class loader of D to load Class C.
If C is an array type, and the element type of the array is an object, and the descriptor of N is similar to "[Ljava/lang/integer", it is loaded according to the previous rule, if the descriptor of n is similar to "Java.lang.Integer", That will generate an array object representing this array dimension and element by the virtual machine.
Sign reference verification before completing to confirm that D has access to C. If not, throw a "illegalaccesserror" exception.
2) field resolution
First, parse the index constant_class_info symbol reference in the field table Class_index item, which is the symbol reference for the class or interface to which the field belongs. If the parse succeeds, the class or interface to which this field belongs is represented by C, and the virtual machine searches for subsequent fields for C.
Returns a direct reference if C itself contains a match, or a recursive lookup of the inherited relationship associated with C, to match. Return success and permission validation.
Throws a Nosuchfielderror exception if it is not found.
3) class method parsing
class method parsing and field resolution is similar, the same can not be found also thrown nosuchmethoderror.
4) Interface Method parsing
From the index in the interface method table Class_index item, if the found C is a class instead of an interface, throw the exception incompatibleclasschangeerror directly.
The following search method and class method parsing are basically the same. No throw exception nosuchmethoderror found.
In addition, the methods in the interface are not subject to access permissions because they are all the default public adornments, and naturally do not throw illegalaccesserror exceptions.Initialization of
The class initialization phase is the final step in class loading, and the initialization phase is the process of executing the Class Builder <clinit> () method.
The <clinit> () method is generated by the compiler automatically collecting statement merges in the assignment actions of all class variables in the class and in static statement blocks (static{} blocks).
Virtual opportunity guarantees that a class () method is properly locked in a multithreaded environment, synchronization, if multiple threads simultaneously initialize a class, then only one thread executes the <clinit> () method of the class, and other threads need to block the wait until the active thread executes < Clinit> () method completed. If there is a lengthy operation in the <clinit> () method of a class, it can cause multiple processes to block.
When it comes to class loading mechanisms, it's essential to talk about class loaders. class Loader
The
Virtual machine design team takes the "fully qualified name of a class to describe a binary byte stream" in the class loader phase to the outside of the Java Virtual machine to enable the application to decide for itself how to fetch the required class. The code module that implements this action is called the class loader. For any class, it is necessary to establish its uniqueness in the Java Virtual machine, together with the class loader that loads it, and each class loader has a separate class namespace. In layman's terms, the two classes are equal, and the first thing to do is that the two classes are loaded as prerequisites for the same classloader. From the Java Virtual machine perspective, there are only two different classloader: one is the boot ClassLoader (BootStrap ClassLoader), which is implemented in the C + + language, is part of the virtual machine, and the other is all the other ClassLoader, These are independent of the virtual machine, are implemented by the Java language, and are inherited from Java.lang.ClassLoader.
from the Java Developer's perspective, the following 3 are most commonly used. The
1) Boot class loader (BootStrap ClassLoader)
is responsible for the path that will be stored in the <java_home>\lib directory, or in the paths specified by the-xbootclasspath parameter. and is the virtual machine recognized class library loaded into the virtual machine memory. The
2) Extended class loader (Extension ClassLoader)
is responsible for loading all the class libraries in the <java_home>\lib\ext directory or in the path specified by the Java.ext.dirs system variable. Developers can use it directly.
3) The return value of the Getsystemclassloader () of the Application class loader
ClassLoader. is responsible for loading the class library specified on the user classpath (ClassPath).
Our applications are loaded with each other by these 3 kinds of loaders, and the relationship between them is as shown:
Parental delegation Model
This is our cliché-only parent delegation model for the ClassLoader. Requires that, in addition to the top-level boot class loader, the rest of the ClassLoader should have its own parent class loader. The parent-child relationship between the ClassLoader is generally not implemented as an inheritance relationship, but instead uses a combination of relationships to use the parent loader's code. The
Parent delegation model works like this: If a class loader receives a request for class loading, it first does not attempt to load the class itself, but instead delegates the request to the parent loader to complete it, as is the case for each class loader. As a result, all load requests should eventually be routed to the top-level boot class loader, and the child loader will attempt to load itself only if the parent ClassLoader has feedback that it cannot complete the load request (its search scope does not find the required class). The advantage of the
using a parental delegation model is that the Java class, along with its classloader, has a hierarchical relationship of precedence. Its implementation is very simple, let's look at the source code
Protected class<?> loadclass (String name, Boolean resolve) throws ClassNotFoundException {synch Ronized (Getclassloadinglock (name)) {//I, check if the class has already been loaded CLASS&L t;?
> c = findloadedclass (name);
if (c = = null) {Long T0 = System.nanotime ();
try {if (parent!= null) {c = Parent.loadclass (name, false);
else {c = findbootstrapclassornull (name); } catch (ClassNotFoundException e) {//ClassNotFoundException thrown if class not F
Ound//From the Non-null parent class loader} if (c = null) {
If still not found, then invoke findclass into 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; }
}
Step:
To check whether it has already been loaded, call the parent loader's LoadClass () method if it is not loaded, and use the Startup class loader as the parent loader by default if the parent loader is empty. If the parent class loader fails, throws an exception and then calls its own Findclass () method to load.