First knowledge of jvm-1. Loading mechanism for Java classes

Source: Internet
Author: User
Tags object object

Reprint: JVM Series---a pure smile

Address: http://www.ityouknow.com/jvm.html

1. What is class loading

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 an object in the heap java.lang.Class that encapsulates the data structure of the class within the method area. The final product loaded by the class is the object that is located in the heap Class , which Class 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
    • To dynamically compile a Java source file into a. class file
2, the life cycle of the class

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.

Load

The first stage of the class loading process is to find and load a class's binary data load, and during the load phase, the virtual machine needs to complete the following three things:

    • Gets its defined binary byte stream through the fully qualified name of a class.
    • Converts the static storage structure represented by this byte stream into the run-time data structure of the method area.
    • An object representing this class is generated in the Java heap java.lang.Class as an access point to the data in the method area.

In contrast to other stages of class loading, the load phase (accurately, the action of getting the binary byte stream of a class during the load phase) is the strongest stage, because developers can either use the system-provided classloader to complete the load or customize their own classloader to complete the load.

When the load phase is complete, the binary byte stream outside the virtual machine is stored in the method area in the format required by the virtual machine, and an object of the class is created in the Java heap so that the java.lang.Class data in the method area can be accessed through the object.

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 validation: Verify that the byte stream conforms to the specification of the class file format, such as whether the 0xCAFEBABE constants in the constant pool have unsupported types with the beginning and the primary and secondary version numbers within the processing range of the current virtual machine.
    • 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 -Xverifynone parameters to turn off most of the class validation measures to shorten the load time of the virtual machine class.

Prepare: Assign memory to the class 静态变量分 and initialize it to a default value

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. This time memory allocation includes only class variables (static), not instance variables, and instance variables are allocated to the Java heap as objects are instantiated when the object is instanced.
    • 2, the initial value set here is usually the default value of the data type 0 (such as 0, 0L, NULL, FALSE, etc.), rather than being explicitly assigned in the Java code value.

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 yet started executing, and the instruction to assign value 3 public static is stored in the class constructor method after the program is compiled <clinit>() . 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.
    • 3. If a property exists in the field attribute table of a class field, that is ConstantValue both final and static, the value of the variable in the prepare phase is initialized to the values specified by the Constvalue property.

Assume that the above class variable value is defined as: public static final int value = 3 ;

At compile time, Javac will generate the Constantvalue property for value, and the virtual machine will ConstantValue assign value 3 based on the setting in the prepare phase. We can understand that the static final constant puts its result in the constant pool of the class that called it at compile time

Parse: Converts 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.

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. If the class has not been loaded and connected, the program loads and connects the class first
    • 2, if the immediate parent class of the class has not been initialized, first initialize its immediate parent class
    • 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
    • To invoke a static method of a class
    • Reflection (e.g. Class.forName(“com.shengsiyuan.Test”) )
    • Initializes a subclass of a class, its parent class is also initialized
    • A class () that is marked as the startup class when the Java Virtual machine starts Java Test , and java.exe runs a main class directly using the command

End Life cycle

In the following scenarios, the Java Virtual machine will end the life cycle

    • Implemented the System.exit() method
    • End of normal execution of the program
    • The program encountered an exception or error during execution and terminated abnormally
    • Java Virtual machine process terminated due to operating system error
3. Class Loader

Looking for the ClassLoader, let's start with a small example

 Package Com.neo.classloader;  Public class classloadertest {     publicstaticvoid  main (string[] args) {        = Thread.CurrentThread (). Getcontextclassloader ();        SYSTEM.OUT.PRINTLN (loader);        System.out.println (Loader.getparent ());        System.out.println (Loader.getparent (). GetParent ());}    }

After running, the output results:

[email protected][email protected] NULL

As can be seen from the above results, there is no ExtClassLoader parent loader, because Bootstrap Loader (the boot ClassLoader) is implemented in C and cannot find a definite way to return the parent loader, so it 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, these classloader need to be loaded into memory by the startup ClassLoader before they 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: a Bootstrap ClassLoader JDK\jre\lib class library (such as Rt.jar, all Java) that is responsible for loading the libraries (such as the JDK, which represents the JDK's installation directory, the same below), or the -Xbootclasspath path specified by the parameters, and can be recognized by the virtual machine. The classes that begin are Bootstrap ClassLoader loaded). The startup ClassLoader cannot be referenced directly by a Java program.
Extension class loader: Extension ClassLoader The loader sun.misc.Launcher$ExtClassLoader is implemented by, it is responsible for loading JDK\jre\lib\ext all class libraries in the directory, or java.ext.dirs paths specified by system variables (such as javax.
Class), developers can use the extension classloader directly.
Application ClassLoader: Application ClassLoader This class loader sun.misc.Launcher$AppClassLoader is implemented by the loader, which is responsible for loading the classes specified by the user classpath (ClassPath), and developers can use the ClassLoader directly, if the application does not have its own classloader. In general, 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 verified before the non-confidence code is executed.
    • 2. Dynamically create custom build classes that meet user-specific needs.
    • 3. Get 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 first 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 into a class object, stored in the buffer. This is why the JVM must be restarted after the class has been modified, and the program's modifications will not take effect
4. 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

Example:

 PackageCom.neo.classloader; Public classLoadertest { Public Static voidMain (string[] args)throwsclassnotfoundexception {ClassLoader loader= HelloWorld.class. getClassLoader ();                 SYSTEM.OUT.PRINTLN (loader); //use Classloader.loadclass () to load a class without executing an initialization blockLoader.loadclass ("Test2"); //using Class.forName () to load the class, the initialization block is executed by default//class.forname ("Test2"); //use Class.forName () to load the class and specify ClassLoader, which does not perform static blocks when initialized//class.forname ("Test2", false, loader);        } }
View Code

Demo class

 Public Class<?> loadclass (String name)throws  classnotfoundexception {        return  False);}
View Code

Switch the loading mode separately, there will be different output results.

Class.forName () and classloader.loadclass () differences

    • Class.forName(): The class's. class file is loaded into the JVM, and the class is interpreted to execute static blocks in the class;
    • ClassLoader.loadClass(): The only thing to do is to load the. class file into the JVM without executing the contents of the static, and only the newinstance will execute the static block.
    • Class.forName(name, initialize, loader)The parameter function can also control whether static blocks are loaded. And only call the Newinstance () method using the call constructor to create the class object.
5. 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 loading a class, it will not try to load the class itself, but instead of delegating the class load request to the parent ClassLoader ExtClassLoader to complete.
    • 2, when ExtClassLoader loading a class, it will not try to load the class on its own, but to delegate the class load request to Bootstrapclassloader "" to complete.
    • 3, if the BootStrapClassLoader load fails (such as $JAVA_HOME/jre/lib not found in the class), will be used ExtClassLoader to try to load;
    • 4, if the Extclassloader also failed to load, it will be used AppClassLoader to load, if the AppClassLoader load fails, the exception will be reported ClassNotFoundException .

ClassLoader Source Analysis:

 PublicClass<?> loadclass (String name)throwsClassNotFoundException {returnLoadClass (Name,false);}protected synchronizedClass<?> loadclass (String name,BooleanResolvethrowsClassNotFoundException {//first determine if the type has been loadedClass C =Findloadedclass (name); if(c = =NULL) {            //if it is not loaded, it is delegated to the parent class to load or delegate to the startup class loader to load            Try {                if(Parent! =NULL) {                     //If there is a parent ClassLoader, delegate to the parent ClassLoader to loadc = Parent.loadclass (name,false); } Else {                //if the parent class loader does not exist, check whether the class is loaded by the startup ClassLoader, by calling the local method native class Findbootstrapclass (String name)c =FINDBOOTSTRAPCLASS0 (name); }            } Catch(ClassNotFoundException e) {//If neither the parent ClassLoader nor the startup ClassLoader can complete the load task, the load function is called itselfc =Findclass (name); }        }        if(Resolve) {resolveclass (c); }        returnC; }

Parental delegation Model meaning:

    • System class prevents multiple copies of the same byte code in memory
    • Ensure safe and stable operation of Java programs
6. Custom class Loader

Typically, we use the System class loader directly. However, sometimes we also need to customize the ClassLoader. For example, the application is to transfer the Java class byte code through the network, in order to guarantee the security, these bytecode has been encrypted processing, then the system ClassLoader cannot load it, so it needs to be implemented by the custom class loader. Custom class loaders are generally inherited from the ClassLoader class, from the above analysis of the loadClass method, we only need to rewrite the Findclass method. Here we demonstrate the process of customizing the ClassLoader with an example:

 PackageCom.neo.classloader;ImportJava.io.*; Public classMyclassloaderextendsClassLoader {PrivateString Root; protectedClass<?> Findclass (String name)throwsClassNotFoundException {byte[] Classdata =loadclassdata (name); if(Classdata = =NULL) {            Throw Newclassnotfoundexception (); } Else {            returnDefineClass (name, Classdata, 0, classdata.length); }    }    Private byte[] loadClassData (String className) {string FileName= root +File.separatorchar+ classname.replace ('. ', File.separatorchar) + ". Class"; Try{InputStream ins=NewFileInputStream (fileName); Bytearrayoutputstream BAOs=NewBytearrayoutputstream (); intbuffersize = 1024; byte[] buffer =New byte[buffersize]; intLength = 0;  while(length = ins.read (buffer))! =-1) {baos.write (buffer,0, length); }            returnBaos.tobytearray (); } Catch(IOException e) {e.printstacktrace (); }        return NULL; }     PublicString Getroot () {returnRoot; }     Public voidsetroot (String root) { This. root =Root; }     Public Static voidMain (string[] args) {Myclassloader ClassLoader=NewMyclassloader (); Classloader.setroot ("E:\\temp"); Class<?> TestClass =NULL; Try{TestClass= Classloader.loadclass ("Com.neo.classloader.Test2"); Object Object=testclass.newinstance ();        System.out.println (Object.getclass (). getClassLoader ()); } Catch(ClassNotFoundException e) {e.printstacktrace (); } Catch(instantiationexception e) {e.printstacktrace (); } Catch(illegalaccessexception e) {e.printstacktrace (); }    }}
View Code

The core of the custom ClassLoader is the acquisition of the bytecode file, and if it is an encrypted bytecode, the file must be decrypted in that class. Since this is just a demonstration, I did not encrypt the class file, so there is no decryption process. Here are a few things to note:

    • 1, the file name passed here needs to be the full-qualified name of the class, that is com.paddx.test.classloading.Test , the format, because the DefineClass method is processed in this format.
    • 2, it is best not to rewrite the LoadClass method, because it is easy to destroy the parental delegation mode.
    • 3, such test class itself can be loaded by the AppClassLoader class, so we can not put in the Classpath com/paddx/test/classloading/Test.class . Otherwise, due to the existence of the parent delegation mechanism, the class will be AppClassLoader loaded directly, not by our custom class loader.

First knowledge of jvm-1. Loading mechanism for Java classes

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.