Java Virtual Machine class loading: principle, implementation and application (excerpt)

Source: Internet
Author: User
Source: http://forums.zdnet.com.cn/cgi-bin/topic.cgi? Forum = 3 & topic = 1446 & START = 0

I. Introduction

The class loading of a Java Virtual Machine (JVM) is the process of loading the bytecode contained in the class file into the JVM and making it part of the JVM. The dynamic loading technology of JVM classes can dynamically load or replace some functional modules of the system at runtime without affecting the normal operation of other functional modules of the system. This article will analyze the class loading system in JVM and discuss the principle, implementation and application of class loading in JVM.

II. Implementation and Application of class loading for Java virtual machines

2.1 Introduction to the loading process

The so-called loading is the process of searching for the binary form of a class or an interface and using the binary form to construct the class object representing this class or this interface, the class or interface name is given. Of course, the name can also be calculated, but it is more common to construct it by searching the source code in the binary format obtained after compilation by the compiler.

In Java, the Class Loader loads a class into a Java Virtual Machine. Three steps are required: Loading, linking, and initialization, the link can be divided into three steps: verification, preparation, and resolution. In addition to resolution, the other steps are completed in strict order. The main work of each step is as follows:

Load: Query and import binary data of classes or interfaces;

Link: perform the following verification, preparation, and resolution steps. The resolution steps are optional;

Verify: Check whether the binary data of the import class or interface is correct;

Preparation: allocate and initialize the storage space for static variables of the class;

Resolution: convert a symbolic reference to a direct reference;

Initialization: Initialize the Java code and static Java code block for activating static variables of the class.

For details and possible errors during class loading and Virtual Machine startup, see Java Virtual Machine specifications and in-depth Java Virtual Machine. Their resource addresses on the Network are: http://java.sun.com/docs/books/vmspec/2nd-edition/html/Preface.doc.html and http://www.artima.com/insidejvm/ed2/index.html. The focus of this article is not described here.

2.2 load implementation

In JVM, class loading is implemented by classloader and its subclass. Java classloader is an important Java runtime system component. It is responsible for finding and loading classes of class files at runtime.

In Java, classloader is an abstract class. lang, you can say that, as long as you understand some important methods in classloader, and then combine the specific process of class loading in the JVM described above, I have a rough grasp of the dynamic loading technology. These important methods include the following:

① Loadcass method loadclass (string name, Boolean resolve) Where the name parameter specifies the name of the class required by JVM, which is expressed in package notation, such as Java. lang. the resolve parameter tells the method whether to parse the class. Before initializing the class, you should consider class resolution. Not all classes need to be parsed, if the JVM only needs to know whether the class exists or find out the super class of the class, it does not need to be parsed. This method is the entry point of classloader.

② Defineclass method this method accepts byte arrays of class files and converts them into class objects. Byte Arrays can be data loaded from a local file system or network. It analyzes bytecode into the data structure during running hours, verifies validity, and so on.

③ Findsystemclass: The findsystemclass method Loads files from the local file system. It looks for class files in the local file system. If it exists, use defineclass to convert the byte array to a class object to convert the file to a class. When running a Java application, this is the default mechanism for JVM to load classes normally.

④ The resolveclass method resolveclass (Class C) resolves the loaded class. If the class has been parsed, no processing will be performed. When the loadclass method is called, the resolve parameter of the loadclass method determines whether to parse the method.

⑤ Findloadedclass method when the loadclass method is called to load a class, call the findloadedclass method to check whether the class has been loaded by the classloader. If the class has been loaded, the class object is returned; otherwise, null is returned. If an existing class is forcibly loaded, a link error is thrown.

2.3 loaded applications

In general, we need to inherit the abstract class Java when using the Virtual Machine class loading. lang. classloader, where the required method is loadclass (). The following operations must be implemented for this method: (1) confirm the name of the class; (2) check whether the requested class has been loaded; (3) check whether the requested class is a system class; (4) Try to get the requested class from the storage area of the Class Loader; (5) define the requested class in the virtual machine; (6) parse the requested class; (7) return the requested class.

All Java virtual machines include a built-in class loader, which is called the root loader (bootstrap classloader ). The special feature of the root loader is that it can only load classes that are known at the design time. Therefore, the VM assumes that the classes loaded by the root loader are safe and trustworthy, it can run directly without passing security authentication. When an application needs to load a class that is not designed at the time of design, it must use a user-defined classloader ). The following is an example of its application.

Public abstract class multiclassloader extends classloader {

...

Public synchronized class loadclass (string S, Boolean flag)

Throws classnotfoundexception

{

/* Check whether class S is in local memory */

Class class1 = (class) classes. Get (s );

/* Class S is already in local memory */

If (class1! = NULL) return class1;

Try/* use the default classloader to load the class */{

Class1 = super. findsystemclass (s );

Return class1;

}

Catch (classnotfoundexception _ ex ){

System. Out. println ("> not a system class .");

}

/* Obtain the byte array of class S */

Byte abyte0 [] = loadclassbytes (s );

If (abyte0 = NULL) throw new classnotfoundexception ();

/* Convert a byte array to a class */

Class1 = defineclass (null, abyte0, 0, abyte0.length );

If (class1 = NULL) throw new classformaterror ();

If (FLAG) resolveclass (class1);/* Resolution class */

/* Add the newly loaded class to the local memory */

Classes. Put (S, class1 );

System. Out. println ("> returning newly loaded class .");

/* Return the mounted and parsed Classes */

Return class1;

}

...

}

Iii. class loading principle of Java Virtual Machine

We already know that a Java application uses two types of class loaders: the root loader (bootstrap) and the User-Defined loader (User-Defined ). The root loader is part of the implementation of the Java Virtual Machine. For example, if a Java Virtual Machine is implemented by a C program at the top of an operating system that already exists and is in use, then the root loader will be part of those C Programs. The root loader loads classes in some default way, including those of Java APIs. During running, a Java program can install a Class Loader defined by the user. The root loader is an inherent part of the virtual machine, but the user-defined class loader is not. It is written in Java and compiled into a class file before being loaded into the virtual machine, and can be instantiated like any other object. The architecture of the Java class loader is as follows:


Figure 1 architecture of Java class loading

The class Loading Model of Java is a proxy (Delegation) model. When JVM requires the Class Loader Cl (classloader) to load a class, CL first forwards the class loading request to its parent loader. CL gets the opportunity to load this class only when the parent loader is not loaded and cannot load this class. In this way, the proxy relationships of all class loaders constitute a tree-like relationship. The root of the tree is the bootstrap classloader of the class, which is expressed as "null" in JVM. The Class Loader except the root loader has only one parent loader. When creating a loader, if the parent loader is not explicitly provided, the JVM uses the default system loader as the parent loader. The proxy structure of the basic class loader in Java is as follows:


Figure 2 proxy structure for Java class loading

The following describes each type of loaders in detail.

Root (bootstrap) Loader: This loader does not have a parent loader. It is part of the JVM implementation and loads the core code of the Runtime Library from sun. boot. Class. Path.

Extension Loader: the inherited parent loader is the root loader, unlike the root loader, which may be related to the operating system at runtime, this class loader is implemented using pure Java code, and it starts from Java. ext. load Code in dirs (Extended directory.

System or Application Loader: The loader is an extended loader. We all know that we need to set the environment variable (classpath) when installing JDK. This class loader is from Java. class. PATH (classpath environment variable) is loaded with code. It is also implemented using pure Java code, and is also the default parent loader of the User-Defined class loader.

Applet Loader: The system loader that loads the code of a small application from a specific directory on the network specified by the user.

When designing a class loader, the following two conditions should be met:

For the same class name, the object returned by the class loader should be the same Class Object

If the classloader cl1 transfers the request for loading class C to the Class Loader cl2. for the following classes or interfaces, cl1 and Cl2 should return the same Class Object:) S is the direct superclass of C; B) S is the direct superinterface of C; c) S is the type of the member variable of C; d) the type of the member method whose s is C or the parameter type of the builder; e) the return type of the member method whose s is C.

Each class that has been loaded to JVM contains information about the class loader that has loaded it. The class method getclassloader can get the class loader that loads this class. Classes recognized by a Class Loader include the classes recognized by its parent loader and its own loaded classes. It can be seen that the class recognized by the class loader is the superset of its own loaded classes. Note that we can get information about the class loader, but the class loader that has been loaded into the JVM cannot be changed.

The class loading process in Java is also the process of Agent loading. For example, the JVM in the Web Browser needs to load a small application testapplet. JVM calls the small Application Loader ACL (applet classloader) to complete the loading. The ACL first requests its parent loader, that is, whether the system loader loads the testapplet to check whether the class is loaded. Because the testapplet is not in the path of the system loader, therefore, if the system loader does not find this class, it will not be loaded successfully. Then the ACL loads the testapplet by itself. The ACL successfully finds the testapplet. Class file through the network and imports it to the JVM. During the loading process, JVM found that testappet was inherited from the superclass java. Applet. applet. Therefore, JVM calls ACL again to load the java. Applet. Applet Class. The ACL again loads the Applet Class in the above sequence. The result is that the ACL finds that its parent loader has loaded this class, so the ACL directly returns the mounted class to JVM, the Applet Class is loaded. Next, the superclass of the Applet Class are also processed. Finally, testapplet and all related classes are loaded into JVM.

Iv. Conclusion

Dynamic loaders of classes are a core JVM technology and are easily overlooked and cause many misunderstandings. This article introduces the principle, implementation, and application of class loading in JVM, especially analyzes the structure and usage of the classloader and how to use the custom classloader to load and execute Java classes, it is hoped that the reader will have a deep understanding of class loading in JVM.

Related Article

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.