What Jvm needs to load is a binary stream, which can be in the form of a .class file or other forms. If you design it according to the loading standards, there will be no big problem.
The following mainly analyzes the two issues of mechanism and standards:
First, let’s take the loading mechanism of Java class files, which is similar to the loading mechanism of variables. It first loads the Class file into memory, then verifies, parses and initializes the data, and finally forms a Java type that the virtual machine can use directly. Since Java adopts JIT mechanism, it will be slow to load, but its advantages are obvious, it has high flexibility and supports dynamic loading and dynamic connections.
Next, let’s talk about the loading process of the class:
The basic process of a class loading is in the following order, but some are not strictly in this order, and some are in the disordered order. For example, dynamic loading requires initialization and then parsing.
1. Loading
It is up to the virtual machine to decide, but there are also cases where the above phase is executed because the following phase is to be executed.
At this time, the virtual machine does three things:
First, read the binary stream of the file through a fully qualified name;
Second, put the static methods and variables in the file into the method area;
Third, generate an object and put it in the heap as an access portal.
Note that the first one is to read the binary stream, and it does not say which file it is read from or where it is read from. Therefore, it creates strong scalability in Java, which can be from Jar, Zip, or from the network layer, database layer, etc.
Mainly the declaration of object and method area.
2. Verification
Ensure that the binary flow meets the requirements of the virtual machine and does not meet the VerifyError.
First, file format verification, whether there are magic numbers, and whether they meet the requirements of Java files;
Second, metadata verification, whether it complies with Java code specifications, such as whether the abstract class is directly instantiated, whether the ordinary class has indirect or direct parent class Object, etc.; Third, bytecode verification, analyzes the data flow and control flow, and ensures that there will be no behavior that harms the virtual machine, such as whether to call non-existent instructions, whether to assign the parent class to the subclass, whether to assign the object to an object of this type, etc.;
Fourth, symbolic reference verification, mainly whether the description of classes, variables, and method can be found, such as whether the file can be found with a fully qualified name, whether it is accessible, etc.
Mainly determine the internal structure
3. Prepare
Assigning an initial value to a class variable is usually a 0 value such as a static variable, without assigning a value to an instance variable.
4. Analysis
The process of converting symbolic references in a constant pool into direct references. The symbolic reference mentioned here refers to the variable type, and direct reference refers to the handle that can be directly located to the object. Class, method, field, interface parsing, obtain the relevant object according to the fully qualified name, and get its type. If there is no access to the class, IllegalAccessError will be thrown, No field NoSuchFieldError will be thrown, No method NoSuchMethodError will be thrown, if it is a class or not, the interface will be thrown.
5. Initialization
Load classes and necessary resources according to program requirements. There are only four situations, and you need to actively initialize before you can perform the next operation, so you must first perform the above four steps.
First, classes with new or static keywords, new generates objects, and static static loads, these two are obviously going to be initialized;
Second, if you use a class, there is nothing you can do about it;
Third, the methods in the reflection class must be initialized, right?
Fourth, the main class of execution, the class that uses the main method. Other passive initialization situations do not need to be considered.
Small examples:
public class SuperClass {static {System.out.println("SuperClass!!");}public static int value = 1;}public class SubClass extends SuperClass {static {System.out.println("SubClass!!");}}public class TestClassLoad {public static void main(String[] args) {System.out.println(SubClass.value);SuperClass superClass = new SubClass();}}SuperClass!!1SubClass!!The execution result shows a problem: When the subclass calls the parent class variable, the subclass is not initialized because the code relationship at this time has nothing to do with the subclass; when the subclass is initialized, the parent class is not initialized again because the parent class has been initialized in the current method body. The only difference between an interface and a parent class is that interface initialization does not require the parent interface, and it will be initialized only when the parent interface is used, and the same class constructor will be generated.
At this time, the class constructor will be loaded and all variables in the class will be initialized. Of course, the parent class will be initialized before the child class.
6. Use
After loading, how to call it, drawing, calculation, etc.
7. Uninstall
The class is no longer called
Whether the two classes are equal mainly depends on the first loading using the same loader, and the second fully qualified name address is the same
Why ask the above questions? Next, we will talk about a loading mechanism of a virtual machine.
From the perspective of Java virtual machines, there are two class loaders, one is called the system loader (Bootstrap ClassLoader), and the other is called the custom loader (extends ClassLoader). This is divided into two, one is called the application loader and the other is called the extension class loader, which is generally defaulted to the former; and our application loading is mainly done by the above three loaders. The relationship between the three is Application>Extension>Bootsrap. The parent delegation mechanism refers to the combination of two pairs. The child loader first calls the parent loader method, and the target object is not found before using the child loader.
The pseudo-code is as follows:
loadClass(String name,boolean resolve){Class c=findLoadedClass()if(c==null){if(parent !=null)c=parent.loadClass(name,false);c=findBootstrapClassOrNull(name);}catch(ClassNotFoundException e){ }if(c==null)c=findClass(name);}Java advocates that we write the logic of our calling class in findClass, which will help us to use the parent delegation mechanism normally.
Destroy 1. Rewrite loadClass
Destroy 2. Use the thread context loader to let the parent loader call the child loader method
Destruction 3. The commonly used method for hot loading is to customize the class loader and overwrite the original bug module - OSGI
However, if the rules between custom loaders are confused and there is a problem of referring to each other at the same time, the class will eventually not be found, and thread deadlock and memory leaks will occur.
Regarding hot repair, also known as plug-ins, the most popular ones are HotFix, Nuwa, DroidFix, AndFix, etc. These frameworks can be found on github or elsewhere. The principles are as above, the methods are diverse, there are coverage, redirection, etc., through configuration, setting actions, etc.; as plug-ins, the following conditions need to be met:
1. Can be installed independently, but cannot be run independently
2. Be backward compatibility, can be expanded
3. It can only run in the host program, and can be disabled or replaced
The above example explanation of Java advanced virtual machine loading mechanism is all the content I share with you. I hope you can give you a reference and I hope you can support Wulin.com more.