As a programmer, just knowing how to use it is far from enough. At the very least, you need to know why you can use it, which is what we call the bottom.
So what is the bottom? I do not think this is a generalized. In my current level of knowledge: For Web developers, TCP/IP, HTTP, and so on may be the bottom layer, for C, C + + programmers, memory, pointers, and so on may be the underlying things. For Java developers, the JVM where your Java code is running may be what you need to understand and understand.
I will be with you in the next few hours to learn the JVM, all from the in-depth understanding of Java Virtual machines: JVM advanced Features and Best Practices (second edition), thanks to the author. This article is the fourth of a series of articles on Java Virtual machine class loading mechanism .
Series one article: JVM series (i): Java memory Area analysis.
Series II: JVM series article (ii): garbage collection mechanism. Series article Third: JVM series (iii): class file content resolution
first, what is the class loading mechanism
In the JVM series (iii): class file content parsing, we learned the details of the class file storage format, the various information described in the class file, which eventually needs to be loaded into the virtual machine before it can be run and used. The focus of this article is on how the virtual machine loads the class file, and what happens when the information in the class file enters the virtual machine.
The virtual machine loads the descriptive data from the class file into memory, verifies and transforms the data to parse and initialize it, and eventually forms a Java type that can be used directly by the virtual machine. This is the class loading mechanism for virtual machines.
In Java, the loading, joining, and initialization of types are done during the program run, and although the performance overhead is increased, the dynamically expanding language feature in Java relies on runtime dynamic loading and dynamic connection implementation. You can even load a section of binary streams from the network at run time as part of your program code.
second, the timing of class loading
The class starts at the time it is loaded into the virtual machine memory, and until the memory is unloaded, the entire lifecycle includes loading, verification, preparation, parsing, initialization, use, and uninstallation. Where validation, preparation, and resolution are collectively referred to as joins.
Load, verify, prepare, initialize, and unload the order of the 5 phases is fixed, the parsing phase is not necessarily, in some cases, the parsing phase may begin at the end of the initialization phase to support dynamic Java binding.
First here we want to explicitly class load. = load. Loading is just one of these stages. So what we're talking about here is the timing of the initialization. (A little around this thing)
when to initialize. There are only 5 cases (called Active references to a class):
1. Encounter new (instantiate object with new keyword), getstatic (Get a static field of a class, except for static fields decorated by the final modifier), putstatic (set a static field for a class, Except for static fields that are decorated by the final modifier and invokestatic (a static method that invokes a class), if the class has not yet been initialized, it must first be initialized with the 4 byte code instruction.
2. When using the method in the Java.lang.reflect package to reflect calls to a class, you must first initialize the class if it is not yet initialized
3. When a class is initialized, if its parent class has not yet been initialized, it must first initialize its parent class
4. When the virtual machine is started, you need to specify a main class (the class in which the main method is located), and the virtual opportunity first initializes this main class 5. When using JDK1.7 Dynamic language support, if a Java.lang.invoke.MethodHandle instance has the final parsing result of Ref_ Getstatic, Ref_putstatic, and Ref_invokestatic method handles, and the corresponding class for this method handle is not initialized, you need to trigger its initialization first.
Passive references are not: 1. Calling the static field of the parent class from a subclass will only initialize the parent class and not initialize the subclass. 2.new classa[10] does not initialize ClassA 3. The final static constant in ClassA, which is referenced by CLASSB, but does not initialize ClassA, because constants are stored in the constant pool of the calling class in the compilation phase and are not directly referenced to the class that defines the constants.
third, the class loading process
1. Loading
Load is a phase of the class loading process, completed before initialization (the time for initialization is already stated).the following 3 things need to be done during the load phase:
1 by a fully qualified name of a class to obtain the definition of this class of binary Byte Throttle 2) Converts the static storage structure represented by this byte stream to the RUN-TIME data structure of the method area 3) generates a Java.lang.Class object representing this class in memory. Access to various data for this class as a method area
The way to get binary byte throttling: Get from the zip package and eventually become the basis for future Jar/ear/war format; From the network access, the most typical application is the applet; Runtime calculation is generated, the most use of this scenario is dynamic agent technology; Generated by other files, the typical scenario is JSP application, that is, the JSP file generated corresponding class classes; Read from the database, relatively rare, some middleware server can choose to install the program into the database to complete the program code in the distribution between the cluster; And so on.
2. Verify
Validation is the first step in the connection phase to ensure that the information contained in the byte stream of a class file meets the requirements of the current virtual machine and does not compromise the security of the virtual machine itself. Because the source of the class file is not necessarily compiled, it can even be written directly with the hexadecimal editor. Therefore, if you do not check the input of the byte stream, the full trust, it is likely to load harmful byte stream caused the system crashes.
Overall, the validation phase is roughly complete with the following 4 stages of testing:
1) file Format verificationThe byte stream conforms to the class file format specification and can be processed by the current version of the virtual machine. For example, whether to start with the magic number 0xCAFEBABE, whether the primary and secondary version number in the current Virtual machine processing scope, Chang constants are not supported constant types (check the constant tag flag) and so on. The primary purpose of this verification phase is to ensure that the input stream is parsed correctly and stored in the method area, in a format that conforms to the requirements for describing a Java type information. Only through this phase of validation, the byte stream will enter the memory of the method area for storage, so the next 3 verification phases are all based on the method area of the storage structure, no longer directly manipulate the byte stream.
2) meta-data validationThis phase is a 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 verification points that may be included are the parent class, whether the parent inherits the Disallowed class (which is final decorated), and if it is not an abstract class, implements all the methods that are required to be implemented in its parent class or interface, the fields in the class, method is inconsistent with the parent class (for example, overriding the final field of the parent class or generating a method overload that does not conform to the rule, such as the method parameters are consistent but the return values are different, etc.);3) byte code verification
Data flow and control flow analysis, that is, the class of the method of validation analysis to ensure that the method of validation of the class is not to do harm to the virtual machine security behavior (such as: to ensure that the jump instructions do not jump to the method body of the byte Code instructions, etc.)
Even if a method passes the bytecode verification, it does not mean that it must be safe (through the program to verify the program logic can not be absolutely accurate)
4 The Symbolic reference verifies the matching checksum of information outside the class itself (the various symbolic references in the constant pool). Typically check: whether a fully qualified name in a symbolic reference that is described by a string can find the corresponding class, and whether there are methods and fields in the specified class that meet the descriptor and the simple name description
3. Prepare
The preparation phase is formally allocating memory for the class variable (the variable being modified by static) and setting the class variable initial value (typically the 0 value of the data type, the specific assignment phase is the initialization phase), and the memory used by these variables is allocated in the method area. If the field property sheet of the Class field contains the Constantvalue property, the preparation stage variable is initialized to the value specified by the Constantvalue property, that is, if a variable definition becomes public final static int a = 123; Compile-time Javac generates a Constantvalue attribute for a, and the staging virtual machine sets a value to 123 according to the Constantvalue setting.
4. Analysis
The parsing phase is the process by which a virtual machine replaces a symbolic reference within a constant pool with a direct reference.
1) Symbolic Reference: a set of symbols to describe the referenced target, the symbol can be any form of literal, as long as the use of ambiguity can be positioned to the target. Symbolic references are independent of the memory layout implemented by the virtual machine, and reference targets are not necessarily loaded into memory
2) Direct reference: direct pointer to the target, relative offset, or a handle that can be positioned indirectly to the target, directly referencing the memory layout implemented by the virtual machine, and if there is a direct reference, the reference target must have been loaded into memory. The virtual machine specification does not specify when the parsing action occurs, Requires only in the execution of Anewarray, Checkcast, GetField, Getstatic, instanceof, Invokeinterface, invokespecial, Invokestatic, Invokevirtual, Multianewarray, New, Putfield, and putstatic the 13 byte-code directives used to manipulate symbolic references, first parse the symbolic references they use.
The following is clear: in Java, a Java class will be compiled into a class file. At compile time, the Java class does not know the actual memory address of the reference class, so only symbolic references can be used instead. For example, the Org.simple.People class references the Org.simple.Tool class, and the people class does not know the actual memory address of the Tool class at compile time, so only the symbolic org.simple.Tool (assuming) can be used to represent the address of the Tool class. When the class loader loads the people class, you can get the actual memory address of the tool class from the virtual machine, so you can replace the symbol Org.simple.Tool with the actual memory address of the tool class and the direct reference address.
5. Initialize
The class initialization phase is the last step in the class loading process. In the previous phase, in addition to the load phase user application can participate through the custom ClassLoader, the other stages are completely driven and controlled by the virtual machine, until the initialization phase, to really start executing the Java program code defined in the class
four, class loader
The virtual machine design team takes the "fully qualified name of a class to describe the binary byte stream" in the class loading phase to the outside of the Java virtual machine, so that the application can decide how to get 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, along with the class loader that loads it, and each class loader has a separate class namespace. That is, the comparison of two classes is "equal" and only makes sense if the two classes are loaded by the same classloader. "Equality" includes the Equals () method, the Isassinablefrom () method, the return result of the Isinstance () method for the class object representing the classes, as well as the use of the INSTANCEOF keyword to determine the affiliation of the object.
Parental delegation Model
From the Java Virtual machine perspective, there are only two different class loaders: One is the boot ClassLoader, a part of the virtual machine itself, and the other is all the other ClassLoader, independent of the virtual machine, all inherited from the abstract class Java.lang.ClassLoader.
From the Java Developer's point of view, the class loader is divided into 3 types:Start class loader (Bootstrap ClassLoader):This class is stored in the <java_home>\lib directory, can not be directly referenced by JAVA programs, users when writing a custom class loader, if you need to delegate the load request to the Boot class loader, then directly use NULL instead.Extended class loader (Extension ClassLoader):This class loader is responsible for loading all the class libraries in the <java_home>\lib\ext directory, which developers can use directly.Application class loader (Application ClassLoader):This class loader is the return value of the Getsystemclassloader () method in ClassLoader, so it is generally called the System class loader, which is responsible for loading the class library specified on the user class path. Developers can use it directly.
The parental delegation model requires that, in addition to the top-level boot class loader, the other classloader should have its own parent class loader. The parent-child relationships between class loaders are generally not implemented as inheritance relationships, but are used to use combinatorial relationships to rifle through the parent loader's code.
working process:
If a class loader receives a request for class loading, instead of trying to load the class on its own, it does so by delegating the request to the parent class loader, which is the case for every class loader, so that all load requests should eventually pass through the top-level boot ClassLoader. The child loader will attempt to load itself only if the parent loader has feedback that it cannot complete the request (the required class is not found in its search scope).
Benefits:The Java class, along with its classloader, has a hierarchical relationship with precedence. For example, class object, which is placed in Rt.jar, regardless of which class loader is to load the class, is ultimately delegated to the startup class loader for loading, so the object class is the same class in the various ClassLoader environments of the program. (determining whether two classes are the same is done by classloader.class this way, so that even if the same class file is loaded with two classloader, they are also different classes).
==============================2015.7.15 added to http://blog.csdn.net/a19881029/article/details/17247165 part of the content: ===== =================
To look at the Loadclassinternal method in the ClassLoader class, the virtual machine calls the method to load the class:[Java] View Plain Copy// this method is invoked by the virtual machine to load a class. private synchronized class loadclassinternal ( String name) throws classnotfoundexception{ return loadclass (name); } //invoking this method is equivalent to invoking LoadClass (Name,false) . public class<?> loadclass (string name) throws ClassNotFoundException { return loadclass (Name, false) ; } //subclasses of classloader are encouraged to override findclass (String), //rather than this method. protected synchronized class<?≫ loadclass (string name, boolean resolve) throws ClassNotFoundException{ // First, check if the class has already been loaded class c = findloadedclass (name); if (c == null) { try { if (parent != null) { c = parent.loadclass (name, false); } else { &Nbsp; c = findbootstrapclassornull (name); } } catch (classnotfoundexception e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { If still not found, then invoke findClass in order