JVM Load Class principle

Source: Internet
Author: User

After the Java compiler compiles the. class file, we need to use the JVM to run the class file. So the first thing to do is to enter the bytecode from the disk into memory, which we call "loading". After loading, we can make a series of pre-run preparations, for example: to open up space for class static variables, to store the constant pool in the method area memory and to implement constant pool address resolution, initialize class static variables and so on. In this article, we'll talk about how the JVM loads class files.

1. The JVM loads the class process

When we use a command to execute a Java program (such as Test.class): Java Test

(1) Java.exe will help us find the JRE, and then find the Jvm.dll located inside the JRE, which is the real Java virtual machine, finally loading the dynamic library and activating the Java Virtual machine.

(2) After the virtual machine activates, it will do some initialization actions, such as reading the system parameters. Once the initialization action is complete, the first class loader ――bootstrap Loader (startup class loader) is generated.

(3) In the initial work done by Bootstrap Loader, in addition to some basic initialization actions, the most important thing is to load the Extclassloader (Extension class loader) in Launcher.java and set its Parent to null. Represents its parent loader as Bootstraploader.

(4) The Bootstrap Loader then asks to load the Appclassloader (user-defined class loader) in Launcher.java, and sets its Parent as the Extclassloader entity that was previously generated. Both loaders exist in the form of static classes.

It is to be noted here that Launcher$extclassloader.class and Launcher$appclassloader.class are loaded by Bootstrap Loader, so the Parent It is not related to which class loader is loaded.

Beginners are very difficult to understand the process, we will be in the following detailed talk about the class loader and "Parent" is what.

2. Class Loader architecture

The JVM load class file must pass through a program called a ClassLoader, which is loaded from the disk file into the memory (the JVM-managed method area) of the byte stream to run the code. Here are a few of the more important concepts:

(1) Start the class loader: Each Java Virtual machine implementation must have a startup class loader. It is only responsible for locating the class to be loaded in the installation path of the system class (the core Java API's class file). The implementation of this loader is written by C + + and is part of the JVM implementation.

(2) Extension class loader and custom class loader: Responsible for loading other class files other than the core Java API. For example, a class file for installing or downloading a standard extension, a classes file found in the Classpath, a classpath for the application to run, and so on. One thing to note here is that the custom class loader is not implemented by the application programmer itself, it is also the JVM

(3) Namespace: A Java Virtual machine maintains a uniquely identified namespace for each class loader. A Java program can load multiple classes with the same fully qualified name multiple times. The Java virtual machines determine the uniqueness of this "multiple classes", so that when more than one class loader loads a class with the same name, in order to uniquely identify the class, it is also preceded by the name of the class loader that loads the class, indicating the namespace in which the class is located. Shows the namespaces associated with two class loaders, and it is clear that different class loaders allow the same class volcano to be loaded.

Namespaces help secure implementations because you can effectively set up a shield between classes that are loaded with different namespaces. In a Java virtual machine, classes within the same namespace can interact directly, and classes in different namespaces cannot even perceive each other unless they explicitly provide a mechanism to allow them to interact. Once loaded, if a malicious class is given permission to access the current class loaded by another virtual machine, it can potentially know something that it should not know about or interfere with the program's normal operation.

3. Parent-Commissioned model

User-defined class loaders often rely on other class loaders-at least dependent on the Startup class loader created at virtual machine startup-to help it implement some class mount requests:. Before version 1.2, the non-startup class loader must explicitly resort to other class loaders. The class loader can request another user-defined class loader to mount a class that is implemented by invoking LoadClass () on the requested user-defined class loader. In addition, the class loader can request the Startup class loader to load the class by calling Findsystemclass (), which is a static method in class ClassLoader.

In version 1.2, the process by which the class loader requests another class loader to load a type is formalized, known as parental delegation mode.

Starting with version 1.2, each class loader, except the Startup class loader, has a "parent" class loader that, before a particular class loader attempts to load a type in a common way, will "delegate" the task to its parents by default-clearing its parents to load the type. The parents then asked their parents in turn to load the type. This delegated process continues up until the startup class loader is reached, typically starting the class loader is the last class loader in the delegation chain. If the parent class loader of a class loader has the ability to load this type. Then this class loader returns this type. Otherwise, the class loader attempts to load the class itself.

When a Java virtual machine starts running, it creates at least one user-defined loader, or more than one, before the application starts. All of these loaders are connected in a Parent-child chain, at the top of which is the startup class loader.

For example, suppose you write an application and run it on a virtual machine. The virtual machine instantiates two user-defined class loaders at startup: an "extension class loader", a "classpath class loader". These class loaders are joined together with the startup class loader in a parent-child delegate chain, as shown in.

The parent of the class path class loader shown is the extension class loader, and the parent of the extension class loader is the Startup class loader. In Figure 2, the Classpath class loader is instantiated as a system class loader. Assuming your program instantiates its network class loader, it indicates the System class loader as its parent.

The following routines illustrate the parent-child relationship of the class loader.

Java code

 Packagetest; ImportJava.net.URL; ImportJava.net.URLClassLoader;  Public classClassloadertest {Private Static intCount =-1;  Public Static voidtestclassloader (Object obj) {if(Count < 0 && obj = =NULL) {System.out.println ("Input object is NULL"; return; } ClassLoader CL=NULL; if(obj! =NULL&&! (objinstanceofClassLoader)) {CL=Obj.getclass (). getClassLoader (); } Else if(obj! =NULL) {CL=(ClassLoader) obj; } Count++; String Parent= "";  for(inti = 0; I < count; i++) {Parent+ = "Parent"; }             if(CL! =NULL) {System.out.println (parent+ "ClassLoader name =" +Cl.getclass (). GetName ());             Testclassloader (Cl.getparent ()); } Else{System.out.println (parent+ "ClassLoader name = Bootstrapclassloader"; Count=-1; }        }          Public Static voidMain (string[] args) {url[] URLs=NewUrl[1]; URLClassLoader UrlLoader=NewURLClassLoader (URLs);        Classloadertest.testclassloader (UrlLoader); }   }    

The output of the above routines is:

ClassLoader name = Java.net.URLClassLoader

Parent ClassLoader name = Sun.misc.launcher$appclassloader

Parent parent ClassLoader name = Sun.misc.launcher$extclassloader

Parent parent Parent ClassLoader name = Bootstrapclassloader

class Loader Request Process

Example 1 above. Change the Main method to:

Classloadertest TC = new Classloadertest ();

Classloadertest.testclassloader (TC);

The output is:

ClassLoader name = Sun.misc.launcher$appclassloader

Parent ClassLoader name = Sun.misc.launcher$extclassloader

Parent parent ClassLoader name = Bootstrapclassloader

While the program is running, the Classpath class loader issues a request to mount the Classloadertest class, and the Classpath class loader must first ask its parent---extension class loader---to find and load the class, and the same extension class loader first asks for the Startup class loader. Because Classloadertest is not a class in the Java API (java_home\jre\lib) and is not on the installed extension path (Java_home\jre\lib\ext), these two types of loaders will return without supplying a loaded class named Classloadertest to the Classpath class loader. The Classpath class loader can only load classloadertest in its own way, and it downloads the class from the current classpath. In this way, classloadertest can play a role in the execution behind the application.

In the example above, the Testclassloader method of the Classloadertest class was first called, and the method referenced the class java.lang.String in the Java API. The Java Virtual Opportunity request loads the class-path class loader of the Classloadertest class to load the java.lang.String. As before, the Classpath class loader first passes the request to its parent class loader, and the request is then delegated all the way to the Startup class loader. However, the Startup class loader can return the Java.lang.String class to the Classpath class loader, because it can find the class so that the extension class loader does not have to look for the class in the installed extension path, nor does the Classpath class loader look for the class in the classpath. The extension class loader and Classpath class loaders only need to return the class java.lang.String returned by the Startup class loader. From this moment on, whenever the Classloadertest class refers to a class named Java.lang.String, the virtual machine can use the Java.lang.String class directly.

4, a classic example of the description

Let's look at the following code:

Java code

 Package Java.lang;      Public class String {      publicstaticvoid  main (string[] args) {                }  }  

Have you found anything different? By the way, we have written a class that is identical to the string in the JDK, with the same package Java.lang, except that our custom string class has a main function. Let's run a little bit:

Java.lang.NoSuchMethodError:main

Exception in thread "main"

Why is this? Our string class is not obviously the main method?

In fact, we can explain the problem by contacting the parent-commissioned model we talked about above.

Running this code, the JVM will first create a custom ClassLoader, called Appclassloader, and link the loader to the delegate chain: Appclassloader, Extclassloader, Bootstraploader.

The Appclassloader then delegates the request to load the java.lang.String to Extclassloader, and Extclassloader delegates to the last boot ClassLoader bootstraploader.

Starting the ClassLoader Bootstraploader can only load the class class in Java_home\jre\lib (that is, the J2SE API), the problem is that there is a java.lang.String in the standard API (note that This class and our custom class are completely two classes). Bootstraploader thought found this class, not hesitate to load the J2SE API in the java.lang.String.

Finally, the above loading error occurs (note that it is not an exception, it is an error, the JVM exits) because the string class in the API has no main method.

Conclusion: We can of course customize a class that is exactly the same as the API, but because the parent-delegate model makes it impossible for us to load a class that we have customized. So the J2SE specification wants our custom package to have its own unique feature (network domain name). Also, this loader principle makes it more secure for the JVM to run programs because it is difficult for hackers to arbitrarily replace the code in the API.

JVM Load Class principle

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.