Java advanced Virtual Machine Loading Mechanism and Java Virtual Machine Mechanism
The Jvm needs to load a binary stream, either in the. class file format or in other forms. There is no major problem in designing according to its loading standards.
The following mainly analyzes the mechanism and standards:
First, the loading mechanism of Java Class files is similar to the loading mechanism of variables. It first loads the Class files into the memory, and then verifies, parses, and initializes the data, finally, Java types that can be directly used by virtual machines are formed. Java uses the JIT mechanism, so loading is slow, but it has obvious advantages and is highly flexible and supports dynamic loading and dynamic connection.
Next we will talk about the loading process of classes:
The basic process of loading a class is in the following order, but there are also not strictly in this order, there is also a disordered order, such as dynamic loading, You have to initialize and then parse.
1. Load
It is determined by the virtual machine, but the above stage is also executed due to the following stages.
At this time, the virtual opportunity will do three things:
1. Read the binary stream of the file with a fully qualified name;
2. Put static methods and variables in the file into the method area;
3. generate an object and put it in the heap as the access entry.
Note that the first one is to read the binary stream without having to read from any specific file or where to read it. Therefore, Java is highly scalable and can be read from Jar and Zip files, it can also be used at the network layer and database layer.
Mainly declarations of objects and methods.
2. Verification
Make sure that the binary stream meets the requirements of the Virtual Machine. If the binary stream does not meet the requirements of the virtual machine, a VerifyError is reported.
1. Verify the file format, check whether there is a magic number, and whether it meets 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 common class has indirect or direct parent class Object, etc. Third, bytecode verification, analyze the data flow and control flow to ensure that the VM is not harmed, such as whether to call a non-existent command and whether to assign the parent class to the subclass, whether to assign an object to an object other than this type;
Fourth, symbol reference verification, mainly including whether the class, variable, and method description can be found, such as whether the file can be found with a fully qualified name, and whether the file is accessible.
Mainly determine the internal structure
3. Preparation
Assign an initial value to a class variable. Generally, the value 0 is a static variable, rather than an instance variable.
4. Analysis
The process of converting the symbol reference in the constant pool into a direct reference. The symbol reference here refers to the variable type, and the direct reference refers to the handle that can be directly located to the object. Class, method, field, interface parsing, get the relevant object according to the fully qualified name, get its type, if there is no access to the class where it is located, it will throw IllegalAccessError, no field NoSuchFieldError, no method NoSuchMethodError, yes. If the class is not an interface, IncompatibleClassChangeError will be thrown.
5. Initialization
Load classes and necessary resources according to program requirements. There are only four cases, and the following operations can be performed only after the initialization is performed. Therefore, the preceding four steps must be performed first.
First, classes with new or static keywords, new generated objects, static loading, these two are obviously to be initialized;
Second, there is a parent class to use the class, which cannot be done;
Third, the methods in the reflection class must be initialized, right;
Fourth, the main class to be executed, the class using the main method. Other passive initialization situations do not need to be considered.
Example:
1 public class SuperClass { 2 static { 3 System.out.println(“SuperClass!!”); 4 } 5 public static int value = 1; 6 } 7 public class SubClass extends SuperClass { 8 static { 9 System.out.println(“SubClass!!”);10 }11 }12 public class TestClassLoad {13 public static void main(String[] args) {14 System.out.println(SubClass.value);15 SuperClass superClass = new SubClass();16 }17 }18 SuperClass!!19 120 SubClass!!
The execution result shows a problem: when the subclass calls the parent class variable, the subclass is not initialized because the code relationship is irrelevant to the subclass. When the subclass is initialized, the parent class is not initialized, because the parent class has been initialized in the current method body. The only difference between an interface and a parent class is that the parent interface is not required for interface initialization. Only the parent interface is used for initialization, and the class constructor is also generated.
When the class constructor is loaded, all variables in the class will be initialized. Of course, the parent class is initialized before the subclass.
6. Use
After loading, how can I call, draw, compute, and so on?
7. Uninstall
Class is no longer called
Whether the two classes are equal mainly lies in the first use of the same loader for loading, and the second full-qualified name and address are consistent
Why do we need to raise the above question? Next we will talk about a Virtual Machine Loading Mechanism.
InJava Virtual MachineThere are two types of loaders, Bootstrap ClassLoader and extends ClassLoader, one is called an Application Loader and the other is called an extension class loader, which is usually the former by default. The loading of our application is mainly completed by the combination of the above three loaders. The relationship between the three is as follows: Application-> Extension-> boot13c. The parent-parent delegation mechanism is a combination of the two. The sub-loader first calls the method of the parent loader, the target object is not found and then the sub-loader is used.
The pseudocode is as follows:
1 loadClass(String name,boolean resolve){ 2 Class c=findLoadedClass() 3 if(c==null){ 4 if(parent !=null) 5 c=parent.loadClass(name,false); 6 c=findBootstrapClassOrNull(name); 7 }catch(ClassNotFoundException e){ } 8 if(c==null) 9 c=findClass(name);10 }
Java advocates that we write the logic of the Self-called class in findClass, which facilitates the normal use of the parent-parent delegation mechanism.
Damage 1. Rewrite loadClass
Damage 2. Use the thread context loader to let the parent loader call the method of the sub-loader.
Damage 3. Hot loading the current common practice is to customize the class loader and overwrite the original bug module-OSGI
However, if the rules between the custom loaders are chaotic and there is a problem of mutual reference, the class will not be found, and the thread deadlock and Memory leakage will occur.
HotFix, also known as plug-ins, is currently popular with HotFix, Nuwa, DroidFix, AndFix, etc. These frameworks can be found on github or elsewhere. The principles are as above and there are various methods, with overwriting and redirection, you can configure and set actions. As a plug-in, the following conditions must be met:
1. It can be installed independently, but cannot run independently.
2. scalability with downward compatibility
3. It can only run in the Host Program and can be disabled or replaced.
Link: http://geek.csdn.net/news/detail/245578
More references: http://www.roncoo.com/article/index