The ClassLoader of the JVM

Source: Internet
Author: User
Tags driver manager garbage collection static class

To support Cross-platform features, the Java language uses source code to compile intermediate bytecode, and then the JVM of each platform interprets how it executes. Bytecode is described in a completely platform-independent manner, Java only gives the specification of bytecode format, and does not specify the final source of bytecode, it can be in addition to the Java language, other than language generation, as long as the bytecode specification is satisfied, can be very good in the JVM to run. Because of this characteristic, has greatly promoted the development of various languages, on the JVM platform appeared a lot of languages, such as Scala,groovy

Because the bytecode source is not restricted, the JVM must check the bytecode for the availability and security of the bytecode before the byte code is formally used, that is, during the load process. 1. JVM Runtime memory Structure partitioning

Before you make a formal presentation, look at the JVM memory structure partition:

Combining the garbage collection mechanism, the heap is refined:

The method area is used primarily in the loading phase:

A method area is a runtime memory region that can be shared by each thread. The structure information for each class is stored, such as the Runtime Constant pool, field and method data, the bytecode content of constructors and common methods, and some special methods that are used in class, instance, and interface initialization.

If the code of the method is considered to be its "static" part, and the temporary data required for a method call to be recorded is considered as its "dynamic" part, the code for each method is only one copy, stored in the method area of the JVM; each time a method is invoked, a new stack frame is allocated on the Java stack of the thread on which the call resides. Used to store temporary data, and the stack frame is automatically revoked when the method returns. 2. Class loading Process

The JVM divides the class loading process into loads, joins, initializes three stages, where the connection phase is subdivided into validation, preparation, and parsing three phases.

These three phases are generally maintained in this order, but there are special circumstances, such as the load phase and the part of the connection phase (part of the verification of bytecode) is interleaved. Again, the parsing phase can be a delay in first-time access to a class, so it may appear after the initialization phase. 2.1 Load

The load phase essentially reads the Java bytecode into the JVM's memory in binary form, and then resolves the binary data stream to the Run-time data structure within the JVM according to the bytecode specification. Java only regulates bytecode, does not stipulate the internal run-time data structure, different JVM implementations can adopt different data structures, these RUN-TIME data structures are stored in the JVM's method area (hotspot The JVM's internal data structure definition can be found in the Hotspot SA to see the objects on PermGen. When the binary of a class is parsed, the JVM eventually generates an instance object of the Java.lang.Class type on the heap, through which it can access the contents of the class in the method area.

The JVM specification does not specify how data from binary bytecode should be generated, in fact, in order to support the scalability of binary bytecode data sources, the JVM provides a callback interface that is open to the external implementation of the JVM by using the fully qualified name of a class to obtain an action that describes the binary bytecode of this class. This is the class loader that we want to talk about later, and if necessary, we can customize some class loaders to achieve some special application scenarios. With the support of the JVM, binary streams can be generated in the following ways:

(1) Read from the local file system

(2) Loading from the network (typical application: Java applet)

(3) loading from Jar,zip,war and other compressed files

(4) Dynamically compiling Java source files (dynamic compilation of JSP)

(5) directly generated by the program. 2.2 Connections

The connection phase is mainly done after loading the verification work, and initialization before the preparation of some work, it is subdivided into three stages.

2.2.1 Verification

Validation is the first step in the connection phase, primarily to ensure that the loaded bytecode conforms to the Java language specification and does not compromise the virtual machine. For example, to verify that this class is not in line with bytecode format, variables and methods are duplicated, data type is not valid, inheritance and implementation of standards and so on. Depending on the content of the validation can be subdivided into 4 stages: file Format verification (this step will be cross with the loading phase), metadata validation, bytecode verification, symbolic reference verification (this phase of validation is often cross with the parsing phase).

2.2.2 Ready

The preparation phase allocates memory for the class's static variables and sets the JVM default initial value. For non-static variables, no memory is allocated for them.

The initial values for each type in the JVM are as follows:

Int,byte,char,long,float,double default initial value is 0

Boolean is False (Boolean is represented in the JVM with int, so the initial value is 0)

Reference type is NULL

For the final static base type or string type, a constant value is used directly (this is actually handled at compile time).

2.2.3 resolution

The parsing process is to find the class, fields, methods, and symbolic references of the class's constant pool, replacing them with a direct reference process.

A. The parsing process is mainly aimed at the constant_class_info,constant_fieldref_info,constant_methodref_info and constant_interfacemethodref in the constant pool _info four kinds of constants.

B. The JVM specification does not specify the time at which the parsing phase occurs, but only provides for the execution of Anewarray,checkcast,getfield,getstatic,instanceof,invokeinterface,invokespecial, Invokespecial,invokestatic,invokevirtual,multinewaary,new,putfield,putstatic These 13 directives are applied to symbolic directives, they are parsed first, and their direct references are obtained.

C. The JVM creates an internal run-time pool for each loaded class (refer to the diagram above), before parsing, a symbolic reference is stored in a Run-time constant pool as a string, and the parsing process is invoked when a symbolic reference is needed during the program's operation. The parsing process is to find the corresponding class entity through a symbolic reference, and then replace the symbol reference with a direct reference. Since a symbolic reference has been replaced with a direct reference, it is not necessary to parse again to return directly to the direct reference when you revisit it later. 2.3 Initialization

The initialization phase assigns the correct initial value to the static variable of the class based on the initialization statement in the user program. Here the initialization execution logic is ultimately embodied in the class constructor method <clinit> () square. The method is generated by the compiler in the compile phase, which encapsulates two parts: the initialization statement of the static variable and the static statement block.

2.3.1 Initialization Execution Time

The JVM specification explicitly prescribes initialization execution conditions that perform initialization as long as one of the following four conditions is met

(1) Instantiate the object through the new keyword, read or set the static variable of the class, and invoke the static method of the class (corresponding to the new,getstatic,putstatic,invokespecial of the four bytecode directives).

(2) The above behavior is performed by reflection method.

(3) Initialization of the parent class is triggered when the subclass is initialized.

(4) as the main class when the program portal runs directly.

2.3.2 Initialization Process

The initialization process consists of two steps:

(1) Initializes a direct parent class if the class exists in a direct parent class and the parent class is not initialized.

(2) If the class currently exists a <clinit> () method, the <clinit> () method is executed.

Note that the initialization of an interface (interface) does not require that its parent interface be initialized first. (interface cannot have a static block)

Conditions for the existence of the 2.3.3 <clinit> () method

Not every class has a <clinit> () method, and there is no <clinit> () method in the following cases:

A. Class has no static variables and no static statement blocks

B. Although static variables are defined in the class, no explicit initialization statements are given.

C. A <clinit> () method is not available if the class contains only the initialization statements of the final static variable, and the initialization statement uses a compile-time expression.

Example:

public class Constantexample {public

    static final int   a = ten;
    public static final Float B = A * 2.0f;
}

After compiling, view the bytecode with Javap-verbose Constantexample, which appears as follows:

{public
static final int A;
  Constant value:int public
static final float B;
  Constant value:float 20.0f public
constantexample ();
  Code:
   stack=1, Locals=1, args_size=1
   0:	aload_0
   1:	invokespecial	#15;//method Java/lang /object. " <init> ":() V
   4:	return
  linenumbertable: line 
   12:0

  localvariabletable: 
   Start  Length  Slot  Name   Signature
   0      5      0    this       lconstantexample;

}

Here because the compiler directly 10, as a constant to deal with, see there is no <clinit> () method exists. Types that can be treated as constants include basic types and string types

For other types:

public class ConstantExample1 {public

    static final int   a = ten;
    public static final Float B = A * 2.0f;
    public static final Date  C = new Date ();
}

Here, although C is declared final, the <clinit> () method is still produced, as follows:

{public
static final int A;
  Constant value:int public
static final float B;
  Constant value:float 20.0f public
static final java.util.Date C;

static {};
  Code:
   stack=2, locals=0, args_size=0
   0:	new	#17;//class java/util/date
   3:	DUP
   4:	invokespecial	#19;//method java/util/date. " <init> ":() V
   7:	putstatic	#22;//field c:ljava/util/date
   ; Linenumbertable:	line
  19:0 line
   14:10

Concurrency of 2.3.4

Under the same class loader domain, each class is initialized only once, and when multiple threads need to initialize the same class, only one thread is allowed to perform the initialization work, while the other threads wait. When the initialization is completed, the thread notifies other waiting threads. 2.4 Distribution status of classes, objects on method areas and heaps during use

First up code

public class Testthread extends Thread implements cloneable {public

    static void Main (string[] args) {
        Testthrea D t = new Testthread ();
        T.start ();
    }

The storage and references that Testthread and related classes run in the JVM above in this code are shown in the following illustration:



where T is a reference to a Testthread object that stores the stack frame space of a thread, the class object instance corresponding to the thread object and the type data is stored on the heap, and the type data is stored in the method area, as mentioned earlier, The symbolic reference in the Testthread type data is substituted for the direct reference during parsing, so the Testthread type data directly references its parent thread and the type data of the interface cloneable it implements.

In the same class loader space, there is only one instance of the class and type data for the class with the fully qualified name. Actually, the instance data of the class and its corresponding class object are referenced by each other. 3. Class Loader

As mentioned above, the class loader is actually open to a callback interface used by the JVM during the loading phase of class loading, and its main function is to obtain a binary byte code that describes this class through the fully qualified name of a class. Of course, the advantages of the ClassLoader are much more than that, it is an important part of the Java security System (the Java security architecture, followed by a dedicated article), while the ClassLoader and class uniqueness of the ClassLoader to identify a class method, Can bring some powerful features to the application, such as HotSwap. 3.1 Parent delegation Model

The uniqueness identification of a class instance in the JVM is the fully qualified name of the class and the loader for that class, which is equivalent to a namespace that isolates the class of the same name.

From the JVM's point of view, there are only two types of loaders, one is implemented by C + + the launch class loader, is part of the JVM, a class is implemented by the Java language Application loader, independent of the JVM.

Some class loaders are defined in JKD:

(1). BootStrap ClassLoader: Start class loader, implemented by C + + code, is responsible for loading in the%java_home%\lib directory, or through the path specified by the-xbootclasspath parameter, and is recognized by the JAVA virtual machine ( The boot class loader cannot be referenced directly by a Java program, such as Rt.jar, a class library whose name does not match, even if it is not loaded in the specified path, and the class library is in memory of the virtual machine.

(2). Extension ClassLoader: Extended class loader, implemented by Sun.misc.launcher$extclassloader, is responsible for loading the%java_home%\lib\ext directory, Or all of the class libraries in the path specified by the JAVA.EXT.DIRS system variable, the developer can use the Extended class loader directly.

(3). Application ClassLoader: Application class loader, implemented by Sun.misc.launcher$appclassloader, is responsible for loading the class library specified on the user classpath classpath. is the return value of the Getsystemclassloader () method in the ClassLoader ClassLoader, the developer can use the Application class loader directly, and if there are no custom ClassLoader in the program, the loader is the default class loader in the program.

Reference ClassLoader source code will find that these classes do not use inheritance to implement the parent-child relationship, but the combination of the way.

Normally, when a class load request is received by each class load, the parent loader is invoked to load it, and if the parent loader fails, the child loader loads. 3.2 Two kinds of active loading mode

There are two ways to actively load classes in your application in Java:

A forname static method of class classes

public static class<?> forname (String className) 
                throws ClassNotFoundException 
//allows specifying whether to initialize and specifying class loaders for classes Public
static class<?> forname (String name, Boolean initialize, ClassLoader loader) throws ClassNotFoundException

The other is the LoadClass method in ClassLoader

Protected synchronized class<?> loadclass (String name, Boolean resolve)//second parameter indicates whether to connect after the reprint (parsing)
	throws ClassNotFoundException public

class<?> loadclass (String name) throws ClassNotFoundException

The above two ways are different, as shown in the following example

public class Initialclass {public

    static int i;
    static {
        i = 1000;
        System.out.println ("Initialclass is init");
    }

public class Initclasstest {public static void main (string[] args) throws Malformedurlexception, classnotfoundexcept
                                               Ion {Class classfromforname = Class.forName ("Com.alibaba.china.jianchi.example.InitialClass",
                                                                  True, the new URLClassLoader (
                                                                                      New url[] {new URL (
                                                                  "file:/home/tanfeng/workspace/springstudy/bin/")},

        InitClassTest.class.getClassLoader ()));  Class Classfromclassloader = (new URLClassLoader (new url[] {new URL ("File:/home/tanfeng/workspace/springstu Dy/bin/")}, INitClassTest.class.getClassLoader ())). LoadClass ("Com.alibaba.china.jianchi.example.InitialClass"); }
}

By running, the Class.forName () method initializes the loaded class, while the Classloader.loadclass () method does not.

We often see that the driver class is loaded in Class.forName () instead of the Classloader.loadclass () method when the database is being manipulated.

Looking at MySQL's driver class implementation, you can see that in the initialization phase of the class, it registers itself in the driver Manager (the static block).

Package com.mysql.jdbc;
public class Driver extends Nonregisteringdriver implements Java.sql.Driver {

	static {
		try {
			Java.sql.DriverManager.registerDriver (New Driver ());
		} catch (SQLException E) {
			throw new RuntimeException ("Can ' t Register driver!");
		}
      ... ...
}
3.3 Application of custom class loader

Analysis of class loader in 3.3.1 Tomcat

3.3.1.1 Tomcat solves the following problems by customizing a set of Class loaders:

(1) The Java class libraries used by the two Web applications deployed on one server are isolated from each other.

(2) Two Web applications deployed on one server can share the Java Shared Class library provided by the server.

(3) The server ensures that its security is not affected by the deployed Web application as much as possible.

(4) Support the HotSwap function of JSP.

Directory Structure of 3.3.1.2 Tomcat

Tomcat is divided into 4 groups of directories based on the shared scope of the Java class Library:

(1) Common directory: can be shared by Tomcat and all Web applications.
(2) Server directory: can only be used by Tomcat, other Web applications are not visible.
(3) shared directory: can be shared by all Web applications, not visible to Tomcat.
(4) Web-inf directory: can only be used by the current Web application and not visible to other Web applications.

3.3.1.3 Tomcat Custom class Loader

These classes of loaders correspond to loading/common/*,/server/*,/shared/*, and/web-inf/* class libraries, where there are multiple WebApp class loaders and JSP class loaders, each corresponding to a WebApp class loader for each WEB application.

Commonclassloader loaded classes can be used by Catalinaclassloader and Shareclassloader ; Catalinaclassloader loaded classes and Shareclassloader loaded classes are isolated from each other; WebappClassLoader can use Shareclassloader loaded classes. But each webappclassloader is isolated from each other; Jspclassloader can only compile class files with JSP files.

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.