Analysis of ClassLoader process of JVM

Source: Internet
Author: User

This article comes from the network: in-depth analysis of Java ClassLoader principles

http://my.oschina.net/zhengjian/blog/133836

ClassLoader process of JVM and loading principle

ClassLoader is the process of looking up a byte-code file (. Class) for a class or interface and constructing a class or interface object by parsing a bytecode file. In Java, the class loader put a class into a Java virtual machine, to go through three steps to complete: Looking for files, links and initialization, where the link can be divided into the verification, preparation and parsing three steps, in addition to parsing, the other steps are strictly in order to complete, the main work of each step is as follows:

Import class byte code: Find class file, import class or interface byte code;

Link: Perform the following validation, preparation and resolution steps, where the parsing step is optional;

Checksum: Check the correctness of binary data of imported class or interface;

Prepare: Allocate and initialize storage space for static variables of class;

Parsing: The symbolic reference is converted to a direct reference;

Initialize: Initializes the Java code and static Java code blocks of the static variables of the class.

Second, the role of classpath: Find class file

The function of classpath is to specify the path to the lookup class: When a class is executed using Java commands (the main method in the class), the class is looked up from the classpath.
Set Classpath mode one:
Set the environment variable classpath, separated by semicolons between multiple paths, or as a jar package path.
Example: Classpath=c:/myclasses/;c/mylib/aa.jar;c:/mylib/bb.jar;.
Note: Case is not case-sensitive in windows, so the specified environment variable is named Classpath or classpath.
Set Classpath mode two:
specified by the-classpath parameter when executing Java commands.
Example: Java-classpath C:/myclasses/;c:/mylib/aa.jar cn.itcast.MainApp
Note: This only uses the classpath specified by this parameter, can not find the class error, will not use the CLASSPATH environment variable!

Conclusion: According to the order specified in Classpath, first find from the previous path, if not found, in the next path to find, until the class byte code or reported Noclassdeffounderror.
Another way to specify the class path is to type the class bytecode file into a jar package and place it in the lib/ext/directory of the JRE so that it can be found directly at execution time without the need to specify CLASSPATH.

How do I package class classes as jar files? The Java installation directory has a tool under the Bin directory: Jar.exe, Eclipse's own export and ant, and maven-like builds can be packaged easily.

Command: Jar CVF jar package name. jar File File

Example: Jar CVF A.jar Helloworld.class test.class

How do I open the jar package?

Use the General decompression tool to do it.

Problem how to use Java tools to execute Myeclipsekeygen.jar?

For example, the MyEclipse6.0 keygen is a jar file.

The operation is as follows: Java-jar Myeclipsekeygen.jar.

Third, the Java environment ClassLoader

Different classes in the Java application environment are loaded by different classloader. The default ClassLoader in a JVM are bootstrap ClassLoader, Extension ClassLoader, and app ClassLoader:

1) Bootstrap ClassLoader called startup class loader, the topmost class loader in the Java class loading hierarchy, is responsible for loading the core class library in the JDK, mainly the Rt.jar, Resources.jar,%jre_home/lib/directory Charsets.jar, you can get where the loader has loaded the relevant jar or class file from the following program. Bootstrap ClassLoader does not inherit from ClassLoader, because it is not a normal Java class, the underlying is written in C + +, embedded in the JVM kernel, when the JVM starts, Bootstrap ClassLoader with the boot, After loading the core class library, and constructing the extension ClassLoader and the app ClassLoader class loader. You can query the native JDK environment by Sun.boot.class.path System Properties:

System.out.println (System.getproperty ("Sun.boot.class.path"));

2) Extension ClassLoader, called the extension ClassLoader, is responsible for loading the Java Extension Class library, which loads all the jars in the java_home/jre/lib/ext/by default.

3) App ClassLoader System Loader, responsible for loading all classes in the classpath of the current Java application.

4) Custom ClassLoader (), the custom ClassLoader must inherit from the abstract class Java.lang.ClassLoader, overriding the Findclass method, which defines how ClassLoader finds class.

The main methods that can be extended are:

Findclass define how to find class

DefineClass loading class file bytecode as class in the JVM

FindResource define how resources are found

You can directly use or inherit existing ClassLoader implementations, such as Java.net.URLClassLoader, Java.security.SecureClassLoader, Java.rmi.server.RMIClassLoader.

Extension ClassLoader and App ClassLoader are all subcategories of java.net.URLClassLoader.

This is the construction method of URLClassLoader:

Public URLClassLoader (url[] URLs, ClassLoader parent)

Public URLClassLoader (url[] URLs) The URLs parameter is an array of classpath URLs that need to be loaded, you can specify the parent ClassLoader, If not specified, it defaults to the ClassLoader of the currently called class as parent.

The code is as follows:

ClassLoader ClassLoader = new URLClassLoader (URLs);

Thread.CurrentThread (). Setcontextclassloader (ClassLoader);

Class Clazz=classloader.loadclass ("Com.company.MyClass"),//The class is loaded using the LoadClass method, which is below the classpath specified in the URLs parameter.

Method Taskmethod = Clazz.getmethod ("Dotask", String.class, String.class);//Then we can do something with reflection.

Taskmethod.invoke (Clazz.newinstance (), "Hello", "World");

Four, the principle of ClassLoader loading class

1. Introduction of principle

ClassLoader uses a parent-delegate model to search for classes, and each ClassLoader instance has a reference to the ClassLoader (not an inherited relationship, a contained relationship), and the virtual machine's built-in ClassLoader (Bootstrap ClassLoader) itself does not have a parent classloader, but can be used as a parent ClassLoader for other ClassLoader instances. When a ClassLoader instance needs to load a class, it attempts to search for a class by itself, delegating the task to its parent classloader, which is checked from top to bottom, first by the topmost class loader bootstrap classloader trying to load, If not loaded, the task is forwarded to the extension ClassLoader attempt to load, if not loaded, then to the app ClassLoader to load, if it is not loaded, then return to the initiator of the delegate, It loads the class into a URL such as a specified file system or network. If none of them are loaded into this class, the ClassNotFoundException exception is thrown. Otherwise, the found class generates a class definition, loads it into memory, and finally returns the class instance object in memory.

2. Why use parents to entrust this model?

Because of this, you can avoid repeated loading. When the father has loaded the class, there is no need for the child classloader to be loaded again. Considering the security factors, let's imagine that if we don't use this delegate pattern, we can use a custom string at any time to dynamically replace the type defined in the Java Core API, so there's a very big security risk, and the way that parents delegate, you can avoid this situation, Because the string has been loaded by the Boot class loader (BOOTSTRCP ClassLoader) at startup, the user-defined ClassLoader can never load a string that he writes, Unless you change the default algorithm for the ClassLoader search class in the JDK.

3, the JVM in the search class, and how to determine the two class is the same?

The JVM determines whether the two classes are the same, not only to determine whether the two class names are the same, but also to determine whether the same class loader instance is loaded. The JVM considers the two classes to be the same only if the two are both satisfied. Even if the two class is the same class bytecode, if it is loaded by two different ClassLoader instances, the JVM will consider them to be two different classes. such as a Java class on the network Org.classloader.simple.netclassloadersimple,javac compiled after the generation of bytecode files Netclassloadersimple.class,classloadera and Classloa Derb these two classloader and read the Netclassloadersimple.class file and define the Java.lang.Class instance to represent this class, for the JVM, they are two different instance objects, but they are really the same byte-code file, if you try to put this CLA When a SS instance generates a specific object for conversion, it throws a run-time exception java.lang.ClassCaseException, suggesting that it is two different types.

V. ClassLoader Loading class Flow

Bootstrap ClassLoader is a JVM level, written by C + +, Extension ClassLoader, App ClassLoader are Java classes, all inherit from URLClassLoader superclass. Bootstrap ClassLoader is initiated by the JVM, then initializes sun.misc.Launcher, sun.misc.Launcher initializes extension ClassLoader, App ClassLoader.

In Java, a class usually has a. class file, but there are exceptions. In the Java Runtime Environment (Java Runtime), each class has a code that appears as a Java object of the first class (first-class), which is an instance of Java.lang.Class. Compiling a Java file, the compiler embeds a public, static, final-decorated type of java.lang.Class, and a domain variable named Class in its bytecode file. Because the public adornment is used, it can be accessed in the following form:

Java.lang.Class Klass = Myclass.class;

Once a class is loaded into the JVM, the same class is not loaded again (remember, the same class). One problem here is what is "the same class"? Just as an object has a specific state, which is identity, an object is always associated with its code (class). Similarly, a class loaded into the JVM has a specific identity, which is identified by its exact match class name (fully qualified class name), which refers to the exact match class name including the package name and the class name. In the JVM, however, a class is uniquely identified with its full name and an instance of the load class ClassLoader. Therefore, if a package named Pg has a class named CL that is loaded by an instance of the ClassLoader Klassloader Kl1, the instance of Cl, that is, C1.class is represented in the JVM (CL, Pg, KL1). This means that two instances of the ClassLoader (CL, PG, KL1) and (Cl, PG, KL2) are different, and the classes they load are therefore completely different and incompatible.

Example 1, test the ClassLoader of the JVM you are using

ImportJava.net.URL; Public classSample { Public Static voidMain (string[] args) {ClassLoader cloader; Cloader=Classloader.getsystemclassloader ();             System.out.println (Cloader);  while(Cloader! =NULL) {Cloader=cloader.getparent ();             System.out.println (Cloader); }             Try{Class<Object> C1 = (class<object>) class.forname ("Java.lang.Object" ); Cloader=C1.getclassloader (); System.out.println ("Java.lang.Object ' s loader" +Cloader); Class<Sample> C2 = (class<sample>) class.forname ("Sample") ); Cloader=C2.getclassloader (); System.out.println ("Sample ' s loader is" +Cloader); }            Catch(Exception e) {e.printstacktrace (); }     }}

Running results on my machine (Java 1.7.2)

[Email protected]

[Email protected]

Null

Java.lang.Object ' s loader is null

Sample ' s loader is [email protected]

The first line indicates that the System class loader instantiates its own class Sun.misc.launcher$appclassloader

The second line indicates that the parent of the System class loader is instantiated from class Sun.misc.launcher$extclassloader

The third line indicates that the parent of the System class loader parent is bootstrap

The four lines indicate that the core class Java.lang.Object is loaded by bootstrap

Line five indicates that the user class sample is loaded by the System class loader

Notice that we see clearly the parent-child relationship between the three ClassLoader classes (not the inheritance relationship), and the parent-child relationship has a classloader-type attribute in the ClassLoader implementation. We can initialize the definition when we implement our own custom ClassLoader, and these three system-defined ClassLoader parent-child relationships are

Appclassloader —————— "(parent) Extclassloader ——————————" (parent) Bootclassloader (null C + + implementation)

Why should the system specify so many ClassLoader classes separately?

The answer is because Java is a dynamic load class, so that can save memory, use what load what, this is the truth, but the system is running at the time do not know our application and need to load what kind of class, then the use of this way of loading

(1) First load the core API, let the system most basic run up

(2) Load extension Class (3) load user-defined class

Import Java.net.URL;  Public class Sample {    publicstaticvoid  main (string[] args)     {        System.out.println (System.getproperty ("Sun.boot.class.path"));         System.out.println (System.getproperty ("Java.ext.dirs"));         System.out.println (System.getproperty ("Java.class.path"));}    }

In the above results, you can see clearly three classloader each load the path of the class, and also know why we write the program, the use of the jar is placed under the classpath of the project, also know why we can not load java.lang.* package! One of the java.lang.* is in the Rt.jar package.


Six summary:

ClassLoader There are bootstrap ClassLoader (JVM default C + + written), Extension ClassLoader, and app ClassLoader

You can also have custom ClassLoader.

The process of loading classes through ClassLoader:

Import class byte code: Find class file, import class or interface byte code;

Link: Perform the following validation, preparation and resolution steps, where the parsing step is optional;

Checksum: Check the correctness of binary data of imported class or interface;

Prepare: Allocate and initialize storage space for static variables of class;

Parsing: The symbolic reference is converted to a direct reference;

Initialize: Initializes the Java code and static Java code blocks of the static variables of the class.

Analysis of ClassLoader process of JVM

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.