Java class loading mechanism and java Loading Mechanism
What is a class loader?
Reads the Java byte code and converts itjava.lang.Class
An instance of the class;
The "same" judgment of the class loader and the class
In addition to loading classes, the class loader can also be used to determine the uniqueness of classes in the Java Virtual Machine.
Even for the same byte code, the classes obtained after being loaded by different class loaders are also different.
Generally speaking, to determine whether the two classes are "identical", the premise is that the two classes must be loaded by the same class loader; otherwise, the two classes are not "identical ".
This refers to the "same", including the Class Object of the Classequals()
Method,isAssignableFrom()
Method,isInstance()
Method,instanceof
Keyword.
Class Loader type
Start the class loader, Bootstrap ClassLoader, load JACA_HOME \ lib, or the class specified by the-Xbootclasspath parameter.
Extension class loader, Extension ClassLoader, loading \ lib \ ext, or the class specified by the java. ext. dirs system variable
Application class loader, Application ClassLoader, and class library in ClassPath
The custom class loader is implemented by inheriting the ClassLoader. Generally, it loads our custom class.
Parent-Child Assignment Model
Similar to other Java classes, the Class Loader must load the Class Loader. Apart from starting the class loader, each class has its parent class loader (parent-child relationship is implemented by combination (not inheritance );
The so-called parent-parent delegation means that each time a class load request is received, the request is first delegates to the parent class loader for completion (all loading requests will eventually be delegated to the top-layer Bootstrap ClassLoader loader ), if the parent class loader cannot complete the loading (the corresponding class is not found in the loader's search range), The subclass tries to load it by itself.
Benefits of parental appointment
- Avoid the same class being loaded multiple times;
- Each loader can only load classes within its own range;
Class loading process
Class loading involves three steps:Load,Connection,Initialization;
For example, it is the full lifecycle of a class from loading, using, and uninstalling. The picture is from references;
Load
Read Binary bytes of this class to the JVM based on the full qualified name of a class (such as cn.edu. hdu. test. HelloWorld. class;
Convert the static storage structure represented by byte streams to the runtime data structure of the Method Area (hotspot chooses to store the Class object in the Method Area, java Virtual Machine specifications do not explicitly require that they be stored in the Method Area or heap area)
Convert to a java. lang. Class Object corresponding to the target type;
Connection
Verify
The verification phase mainly includes four verification processes: File Format verification, metadata verification, bytecode verification, and symbol reference verification;
Preparation
Allocate memory space for all static variables in the class, and set an initial value for it (because no object is generated, the instance variables will not be within the scope of this operation );
Analysis
Convert all symbol references in the constant pool to direct reference (obtain the pointer or offset of a class or field or method in the memory to directly call this method ). This phase can be executed after initialization.
Initialization
- In the preparation phase of the connection, class variables have been assigned an initial value required by the system. In the initialization phase, class variables and other resources are initialized according to the logic written by the programmer, for example:
public static int value1 = 5; public static int value2 = 6; static{ value2 = 66; }
Both value1 and value2 are equal to 0 in the preparation phase;
In the initialization phase, value1 and value2 are equal to 5 and 66, respectively;
- All class variable initialization statements and static code blocks are stored in the collector by the front-end compiler during compilation and stored in a special method. This method is the <clinit> method, class/interface initialization method. This method can only be called by JVM during class loading;
- The sequence collected by the compiler is determined by the sequence in which the statements appear in the source file. The static statement block can only access the variables defined before the static statement block;
- If the superclass has not been initialized, The superclass is initialized first, but the <clinit> method that calls the superclass is not displayed in the <clinit> method, the JVM is responsible for ensuring that the <clinit> method of a class has been executed before it is executed.
- The JVM must ensure that during the initialization of a class, if multiple threads need to initialize it at the same time, only one of the threads can perform Initialization on it, and the other threads must wait, other waiting threads are notified only after the active thread completes class initialization. (So we can use static internal classes to implement thread-safe Singleton mode)
- If a class does not declare any class variables, and there is no static code block, there can be no class <clinit> method;
When to trigger Initialization
Custom Class Loader
To create your own class loader, you only need to inherit the java. lang. ClassLoader class and overwrite its findClass (String name) method, that is, how to obtain the byte code stream of the class.
If you want to comply with the parent-child delegation specification, rewrite the findClass method (User-DefinedClass loading Logic); Rewrite the loadClass method if it is to be damaged (the specific logical implementation of parent-child delegation).
Example:
Package classloader; import java. io. byteArrayOutputStream; import java. io. file; import java. io. fileInputStream; import java. io. IOException; import java. io. inputStream; class TestClassLoad {@ Override public String toString () {return "class loaded successfully. ";}} Public class PathClassLoader extends ClassLoader {private String classPath; public PathClassLoader (String classPath) {this. classPath = classPath; }@ Override protected Class <?> FindClass (String name) throws ClassNotFoundException {byte [] classData = getData (name); if (classData = null) {throw new ClassNotFoundException ();} else {return defineClass (name, classData, 0, classData. length) ;}} private byte [] getData (String className) {String path = classPath + File. separatorChar + className. replace ('. ', File. separatorChar) + ". class "; try {InputStream is = new fileindium UtStream (path); ByteArrayOutputStream stream = new ByteArrayOutputStream (); byte [] buffer = new byte [2048]; int num = 0; while (num = is. read (buffer ))! =-1) {stream. write (buffer, 0, num);} return stream. toByteArray ();} catch (IOException e) {e. printStackTrace ();} return null;} public static void main (String args []) throws ClassNotFoundException, InstantiationException, IllegalAccessException {ClassLoader pcl = new PathClassLoader ("D: \ ProgramFiles \ Program senew \ workspace \ cp-lib \ bin "); Class c = pcl. loadClass ("classloader. testClassLoad "); // note that the package name System must be included. out. println (c. newInstance (); // print class loaded successfully .}}
JAVA hot deployment implementation
First, let's talk about hotswap. Hot deployment can automatically detect changes in the class file and update the class behavior during runtime without restarting the Java Virtual Machine. A Java class is loaded through a Java Virtual Machine. After the Class file of a class is loaded by the classloader, a corresponding Class object is generated, and then an instance of the class can be created. The default Virtual Machine behavior will only load classes at startup. If a class needs to be updated later, the compiled class file will be replaced. the Java Virtual Machine will not update the running class. To achieve hot deployment, the most fundamental way is to modify the source code of the Virtual Machine and change the classloader loading behavior so that the virtual machine can listen to class file updates and reload class files, such behavior is very destructive, and it has paved the way for subsequent JVM upgrades.
Another friendly method is to create your own classloader to load the class to be listened to, so that you can control the class loading time and implement hot deployment.
The above content is mainly organized from the network and added to some personal understandings.
References:
Https://www.ibm.com/developerworks/cn/java/j-lo-hotdeploy/
Https://askingwindy.gitbooks.io/gitbook-java-interview-note/content/jvm/classloader/classloader.html
Https://segmentfault.com/a/1190000004597758
Https://www.ibm.com/developerworks/cn/java/j-lo-classloader/