A Free Trial That Lets You Build Big!
Start building with 50+ products and up to 12 months usage for Elastic Compute Service
Originally wanted to write a blog about the Java class loading mechanism, later found that the subject is a bit large, which involves too much detail, a blog post, words I am afraid can not speak clearly, so decided from the whole to the local, first to talk about the life cycle of class, from the overall grasp a class from "Born" to "apoptosis" process, It involves the class loading, using, unloading and so on each stage, has the whole cognition, then thorough detail and unifies the concrete example, discusses the loading principle, the class loader and so on related knowledge. Let the blogger lead you to the first journey today: The life cycle of the class is detailed. the life cycle of a class
The lifecycle of a class is the process of loading (Loading), validating (verification), preparing ( preparation), parsing (resolution), initialization (initialization), use (using), and uninstall (unloading) 7 phases, as shown in the following illustration:
The verification, preparation, parsing three stages collectively referred to as the connection (linking), while loading, connection, initialization can be collectively referred to as class loading process , so we can sometimes say that the life cycle of the class contains loading, connection, initialization, use and uninstall of these 5 phases, or the class load, use, uninstall these 3 stages.
Back to the diagram above, load, verify, prepare, initialize, and uninstall the starting order of the 5 phases is OK, as shown in the arrow in the figure. The emphasis is placed on "start order" because the order is only the order of the start time of each phase, rather than the sequence of progress or completion, and these phases are usually mixed in each other . such as loading and verification, not to say that we have to wait until the completion of the loading, before beginning the verification phase, in the loading phase, will be interspersed with a variety of inspection actions, or even the format is not in line with the word throttling, how to correctly resolve the static data structure in which to transform into the method area of the data structure. For the parsing phase, the start time is special , either starting at the load stage (parsing the symbol references in the constant pool) or starting after the initialization phase (dynamic binding of the Java language is supported).
Let's take a look at what's going on at each stage. one, class loading process
The process of loading a class contains three stages of loading , connection , and initialization . 1.1 Load
Loading is the first phase of the class loading process, when the virtual machine will find and load the binary data of the class, which is divided into three steps: obtaining a binary byte stream that defines the class by its fully qualified name. Converts the static storage structure represented by this byte stream into the RUN-TIME data structure of the method area. Generates a java.lang.class object representing this class in memory as an access point to the various data for this class in the method area.
These three belong to the contents of the virtual machine specification, only indicate what to do, the concrete implementation to the virtual machine to achieve their own arrangements, which gives the virtual machine implementation and specific applications enough flexibility. For the first article, it does not indicate the storage form of the binary byte stream that defines the class (class file, zip package), source (local file system, memory, or network), and how to get (both read and dynamically generated from existing static resources), and thus have the following diverse possibilities: reading from a ZIP package , which is the basis for supporting class loaders to load class from the JAR, EAR, and WAR format files later. To get byte streams from the network , the applets we know are typical applications of this scenario. program dynamically generated byte stream , this scenario is the most application of dynamic agents, through bytecode technology dynamically generated proxy class binary byte throttling. compiled from files other than Java source files , such as JSP files, Scala source files, and so on.
For the "memory" described in article three, the virtual machine specification does not specify whether it is in the Java heap or the method area, and for the HotSpot virtual machine that we are most familiar with, it is stored in the permanent generation of the Java heap. In fact, the permanent generation is unique to the HotSpot virtual machine, which is the specific implementation of the concept of the method area in the Virtual machine specification (JDK1.7 and below ), and for other virtual machines (such as IBM J9), there is no permanent generation, The relationship between the method area and the permanent generation is beyond the scope of Ben Boven's discussion.
After the completion of the loading phase, the original definition of the binary byte stream of the class is stored in the method area according to the required format of the virtual machine, where the storage format depends on the implementation of the virtual machine, there are differences, the virtual machine specification does not specify the specific data structure of this area.
note points about the load phase : The loading of an array class is special, it is not created by the ClassLoader itself, but is created directly by the Java Virtual machine, but the element type of the array class (the element type that removes the type after all dimensions, such as a, is a) is loaded by the class loader. For example, for type Org.sherlockyb.test.HelloWorld, define one-dimensional array class helloworld HWS = new Helloworld, the virtual opportunity directly creates the name "[ Lorg.sherlockyb.test.HelloWorld the array class, and initializes it. class Loader
The first step in the load phase of the previous section-"Get a binary byte stream that defines this class with the fully qualified name of a class". Is the only thing the ClassLoader does, the ClassLoader is an important cornerstone of the Java technology system, which plays an important role in such areas as class hierarchy, OSGi, thermal deployment, code encryption, About it we do not do a detailed introduction, there will be a separate blog in-depth discussion. Loading Time
The virtual machine specification does not enforce when the loading phase starts, and the virtual machine realizes the free grasp. In the case of HotSpot virtual machines As we know it, there are two scenarios: preload . The virtual machine will preload the class file in the Rt.jar at startup, including java.lang.*, java.util.*, java.io.* , and other run-time classes that are commonly used. run time load . When a virtual machine needs a class while it is running, it loads if its class is not loaded. 1.2 Connections
The connection can be subdivided into three phases: validation, preparation, and parsing. Validate
The first phase of the connection ensures that the stream of bytes loaded from the class file meets the requirements of the current virtual machine and does not compromise the security of the virtual machine itself . This phase will be verified as follows: file format Verification : Determines whether the current byte stream conforms to the class file format specification. If it starts with the magic number of the class file, whether the primary and secondary version number is within the scope of the current virtual machine, the type of constant in the constant pool is Oxcafebabe , and so on. The purpose of the verification is to ensure that the byte stream can be correctly parsed and stored in the method area, after verification, will be stored in the method area, the subsequent check action is based on the method area of the storage structure, no longer directly manipulate the byte stream. meta-data validation : Semantic analysis to determine whether the information described conforms to the requirements of the Java language specification. If the class has other parent classes in addition to Java.lang.Object , whether the parent class of the class inherits byte-code verification of the final class that is not allowed to inherit: By analyzing the data flow and the control flow, it is possible to judge whether the program semantics is legitimate and logical. such as ensuring that a jump instruction does not jump to a byte code instruction other than the method body, and that the type conversion in the method body is valid. symbol Reference Checksum : Occurs when a symbolic reference is converted to a direct reference in the parsing phase to ensure that the parse action executes correctly. Whether the corresponding class can be found by a fully qualified name that is described by a string in a symbolic reference.
As you can see from the above, the verification phase is very important to the security of the virtual machine, but it is not necessary , it does not affect the run-time of the program, if the referenced class has been reused and validated, then you can consider using the-xverifynone parameter to close most of the class validation measures, To shorten the time that the virtual machine class loads. Typically, the class files that are loaded by the application are compiled by our local or server JDK. We are all sure that it meets the requirements of the virtual machine, for such a class file does not need to be validated, mainly like a class byte stream loaded from the network or a byte stream generated by dynamic bytecode technology , it must be rigorously validated for security reasons. Ready to
The only thing to do in the prep phase is to allocate memory for the class's static variables and initialize it to the default value. Note that the initialization here and the "initialization phase" that follows will be different and easily confusing. these memory are allocated in the method area . Some caveats: There are two perspectives for initializing to default values: From the Java application level, the corresponding 0 values are set for different types, such as int, long, and byte integers corresponding to 0, for float, The double floating-point number is 0.0, and the reference type is null. There is a 0-value mapping table, specifically not in this list, from the JVM level, is actually allocated a full 0 value of memory, but different data types for 0 values have different interpretation meaning, this is the Java compiler automatically for us to do. If the static variable of a class is final , that is, the Constantvalue property exists in its Field property sheet, it is initialized to the value specified by the program at the preparation stage, for example, to the public static final int len = 5, the value of Len in the preparation phase has been set to 5. In fact, for the final class variable, the result is placed in the constant pool of the class that called it at compile time, and the access of such a class variable does not trigger the initialization phase of the class to which it belongs. parsing
This phase turns the symbolic reference of a class in a constant pool into a direct reference. A symbolic reference is a set of literal quantities used to describe a goal, which is a static placeholder that is independent of the memory layout, while a direct reference is run-time, a pointer to a target in memory, a relative offset, or a handle that is indirectly positioned toward the target. The parsing work is replaced with a direct reference for class or interface, field, class method, interface method, method type, method handle, and call qualifier, 7-class symbolic references.
The virtual machine specification stipulates that in the implementation of Anewarray, Checkcast, GetField, Getstatic, instanceof, invokedynamic, Invokeinterface, Invokespecial, Invokestatic, Invokevirtual, LDC, Ldc_w, Multianewarray, New, Putfield , and putstatic These 16 byte-code directives for manipulating symbolic references, You must parse the symbol reference first. As for the specific time is not required, to the virtual machine to achieve their own decision: The class is loaded on the constant pool of symbolic references to resolve (static instructions, except invokedynamic), or wait until a symbolic reference will be used before parsing (dynamic instruction: invokedynamic, To support dynamic binding). 1.3 Initialization
Assigns the program's initial value to the static variable of the class. There are two ways to set an initial value on a class variable in Java: When declaring a class variable, specify the initial value and the static code block to assign a value to the static variable. Let's take a look at the initialization step of the class: If the class has not been loaded and connected, load and concatenate the class if the direct parent class of the class is not initialized. Initializes its parent class (the interface does not have this rule) if the class has initialization statements (Assignment statements and static code blocks), executes the initialization statement sequentially, in the order stated in the code
We can learn the principle of the above initialization step from the byte code level,
When compiling Java source files, the compiler automatically collects the assignment operations of all class variables in the class and the statements in the static statement block (as stated in the source code ), merges them to produce the initialization time
The virtual machine specification strictly stipulates that the initialization phase of the class is triggered immediately when a proactive reference to a class occurs. Active references have and are only in the following 5 cases: When you encounter a new,getstatic,putstatic , or invokestatic 4-byte code, If the class is not initialized, it triggers its initialization first. From the Java code level, it is time to instantiate an object with the new keyword, read or set the static field of the class (except for thefinal modified constant field), and invoke the static method. When you use the Java.lang.reflect package method to reflect calls to a class, such as Class.forName (...). When a class is initialized, the initialization of its parent class is triggered (the interface has no such rule) if its parent class is not yet initialized. When a virtual machine is started, the user specifies a main class (including the Main method), which initializes the class first. For ref_getstatic, ref_putstatic, Ref_invokestatic method handles (using the dynamic properties of JDK1.7), the corresponding class is initialized if it is not yet initialized.
In addition, all other references to classes are passive references and do not trigger initialization. second, the use of the class
including active and passive references, which are described in the previous section, we enumerate several instances of passive references: static fields that invoke the parent class through subclasses do not trigger subclass initialization. Referencing a class through an array definition does not trigger initialization of the class. For example, a arr = new A does not trigger the initialization of a. Calling a constant field of B in Class A does not trigger the initialization of B. Because this constant field is stored in a constant pool that invokes class A at compile time, there is no direct reference to the definition Class B in nature. third, class of unloading
A class can be unloaded when it is judged to be a useless class. The conditions are harsh and require the following: All instances of the class have been reclaimed. The ClassLoader that loaded the class has been reclaimed. The corresponding Java.lang.Class object for this class is not referenced anywhere.
The virtual machine can reclaim the useless class which satisfies the above 3 conditions, but it is not inevitable that the recycle can be controlled by the-XNOCLASSGC parameter. Note : The frequent custom classloader scenarios such as a large number of uses of reflection, dynamic proxies, and dynamically generated JSPs, as well as OSGi, require that the virtual machine have class uninstall capabilities to ensure that the permanent generation (especially the Hotspot virtual machine) does not overflow. Summary
At last it was "a cursory" way to put the life cycle of the Java class through, believe that when the life cycle of the class, we will immediately emerge from the class life cycle of the outline, there are stages, each stage is about to do something, what attention points, so that the purpose of this blog is achieved. Master the overall situation, the next is the details of the discussion, such as the verification phase of the bytecode verification, the actual is very complex, the virtual machine specifically for this to do a lot of optimization; again, for example, the parsing phase, 7-class symbols refer to their different parsing details, and so on. After that, the author will be a separate blog, for class loaders, parsing phase, etc. for detailed analysis, please look forward to.
Sync Update to Original
Start building with 50+ products and up to 12 months usage for Elastic Compute Service