In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article will explain in detail how to optimize the compile and run time of Java in the JVM virtual machine. The content of the article is of high quality, so the editor will share it for you as a reference. I hope you will have some understanding of the relevant knowledge after reading this article.
Java compile-time optimization
The compilation time of the java language is actually an uncertain operation, because it can be divided into three types of compilation processes:
1. Front-end compilation: convert .java files into .class files
two。 Back-end compilation: converting bytecode to machine code
3. Static pre-compilation: compile .java files directly into local machine code
Since JDK1.3, the virtual machine design team has focused performance optimization on the back-end real-time compilation, so that those Class files that are not generated by Javac (such as Class files in JRuby, Groovy and other languages) can also enjoy the benefits of compile-time optimization.
* the optimization process of real-time compilation in Java at run time is more important for program operation, while the optimization process of front-end compilation time at compile time is more closely related to program coding.
Early (compilation time) optimization the early compilation process is mainly divided into three parts: 1. The process of parsing and filling symbol table: lexical and grammatical analysis; filling symbol table 2. Annotation processing process of plug-in annotation processor 3. Semantic analysis and bytecode generation: label checking, data and control flow analysis, paraphrase sugar, bytecode generation generics and type erasure
The generics in Java only exist in the program source code. In the compiled bytecode file, they have been replaced with the original primitive types, and the forced transformation code has been inserted in the corresponding places.
Examples before generic erasure public static void main (String [] args) {Map map = new HashMap (); map.put ("hello", "hello"); System.out.println (map.get ("hello"));} examples after generic erasure public static void main (String [] args) {Map map = new HashMap (); map.put ("hello", "hello") System.out.println ((String) map.get ("hello"));} automatic boxing, unpacking and traversal loops
Automatic boxing and unboxing are converted into corresponding wrapper and restore methods after compilation, such as Integer.valueOf () and Integer.intValue (), while the traversal loop restores the code to the implementation of the iterator, and the variable length parameter becomes an array type parameter.
However, the "= =" operations of wrapper classes do not automatically unpack without arithmetic operations, and their equals () methods do not handle the relationship of data transformation.
Conditional compilation
The Java language can also do conditional compilation by using if statements with constant conditions, which are "run" during the compilation phase:
Public static void main (String [] args) {if (true) {System.out.println ("block 1");} else {System.out.println ("block 2");}} decompilation result of compiled Class file: public static void main (String [] args) {System.out.println ("block 1");}
It can only be if statements with constant conditions, which is also the syntax sugar of Java language. According to the true or false values of Boolean constants, the compiler will eliminate untenable blocks of code in the branch.
Late (runtime) optimization interpreter and compiler
The Java program is initially interpreted and executed through the interpreter. When the program needs to be started and executed quickly, the interpreter can first play a role to save the compilation time and execute immediately; when the program runs, with the passage of time, the compilation time gradually plays a role, compiling more and more code into local code to achieve higher execution efficiency. Interpreting execution saves memory and compiling execution improves efficiency. At the same time, the interpreter can be used as an "escape door" when the compiler is radically optimized, allowing the compiler to choose some optimization means that can improve the running speed most of the time according to the probability. When the assumption of radical optimization is not true, it will continue to be executed by returning to the interpreted state through inverse optimization.
There are two real-time compilers in the HotSpot virtual machine, called Client Compiler (C1 compiler) and Server Compiler (C2 compiler). By default, the interpreter works directly with one of the compilers. Which compiler depends on the running mode of the virtual machine, or you can specify it yourself. If the virtual machine is forced to run in "interpretation mode", the compiler is not involved at all. If the virtual machine is forced to run in "compilation mode", the compiler mode is preferred to execute the program. The interpreter still has to intervene in the execution process when the compilation cannot be carried out.
Hierarchical compilation strategy hierarchical compilation strategy is enabled as the default compilation strategy in JDK1.7 's Server mode virtual machine, which includes: layer 0: program interpretation and execution, the interpreter does not turn on performance monitoring function, which can trigger layer 1 compilation; layer 1: C1 compilation, compiling bytecode into native code for simple and reliable optimization, and adding logic to performance monitoring if necessary Layer 2: C2 compilation, which also compiles bytecode into native code, but initiates some optimizations that take a long time to compile, and even makes some unreliable radical optimizations based on performance monitoring information. After the implementation of hierarchical compilation, C1 and C2 will work at the same time, C1 will get higher compilation speed, C2 will get better compilation quality, and will no longer have to undertake the task of performance monitoring information during interpretation and execution. There are two types of "hot code" that will be compiled by the real-time compiler during the run: 1. Method called multiple times: compilation triggered by method call, which belongs to JIT compilation mode 2. Loop body executed multiple times: the whole method is also used as the compilation object, because compilation occurs during method execution, so there are two ways to detect hotspots in stack replacement (OSR compilation): 1. Hotspot detection based on sampling: the virtual machine periodically checks the top of the stack of each thread, and if a method often appears at the top of the stack, it is determined to be a "hot method". (simple and efficient, you can get the call relationship of the method, but it is easy to be affected by thread blocking or other external factors to disturb hot spot detection) 2. Hotspot detection based on counting: the virtual machine sets up a counter for each method, counting the number of times the method is executed, and exceeding a certain threshold is a "hot method". (counters need to be maintained for each method, and the calling relationship of the method cannot be obtained directly, but the statistical results are accurate and rigorous.)
The HotSpot virtual machine uses the second, which prepares two types of counters for each method: the method call counter and the backside counter. The following figure shows that the method call counter triggers real-time compilation:
If no settings are made, the execution engine continues to enter the interpreter to execute bytecode in an interpreted manner, and the compiled version will not be used for the next call until the submitted request is compiled by the compiler. In addition, the value of the method call counter is not an absolute number of times, but the number of times called over a period of time, which is halved, which is called the heat attenuation of the counter.
The following figure shows that the back counter triggers real-time compilation:
The backside counter has no heat decay process of the counter, so it counts the absolute number of times, and when the counter overflows, it also adjusts the value of the method counter to the overflow state. so that the standard compilation process is performed the next time you enter the method.
Compiler optimization technology
The virtual machine design team focuses almost all the optimization measures on the code on the just-in-time compiler, so what exactly does the compiler do during compilation? Here are some of the most representative optimization techniques:
Common subexpression elimination
If an expression E has been evaluated and the values of all variables in E have not changed since the previous calculation, then this appearance of E becomes a common expression and can be directly replaced with the previous result.
Example: int d = (c b) 12 + a + (a + b c) = > int d = E 12 + a + (a + E)
Array boundary check elimination
Access to array elements in Java language requires a range check of upper and lower bounds, and there is a conditional decision operation for each read and write, which is undoubtedly a burden. As long as the compiler can determine that the value range of the loop variable is always within the length of the array through data flow analysis, then the upper and lower bounds can be eliminated in the whole loop, which can save many conditional judgment operations.
Another method is called implicit exception handling, which is used in the judgment of Java hollow pointer and the check of divisor 0 in arithmetic operation:
If (foo! = null) {return foo.value;} else {throw new NullPointException ();} after using implicit exception optimization: try {return foo.value;} catch (segment_fault) {uncommon_trap ();} implicit exception optimization is worthwhile when foo is rarely empty, but foo is often empty, which slows down the program, and the HotSpot virtual machine automatically selects the best solution based on the Profile information collected at run time.
Method inline
Method inlining can not only remove the cost of method calls, but also establish a good foundation for other optimizations, so various compilers generally put inline optimization at the forefront of the optimization sequence. however, because the methods of Java objects are virtual methods by default, method calls need to be polymorphic at run time, in order to solve the inline problem of virtual methods. First of all, the technology of "Type inheritance relationship Analysis (CHA)" is introduced.
1. In inline, if it is a non-virtual method, you can directly inline 2. Encounter virtual method, first of all, according to CHA to determine whether there are multiple target versions of this method, if there is only one, you can directly inline, but you need to reserve a "escape door", called guardian inline, if in the process of subsequent execution of the program, load new classes that lead to changes in inheritance relations, you need to abandon the compiled code, return to the interpreted state of execution, or recompile. 3. If CHA determines that there are multiple target versions of this method, the compiler will use "inline cache". The first call cache records the version information of the method recipient, and each call compares the version. If it is consistent, it can always be used. If it is inconsistent, cancel the inline and find the virtual method table for method dispatch.
Escape analysis
The basic behavior of escape analysis is to analyze the dynamic scope of an object. When an object is referenced by an external method, it is called method escape; when accessed by an external thread, it is called thread escape. If you can prove that an object will not be referenced by an external method or process, you can make some optimizations for this variable:
1. Stack allocation: if it is determined that an object will not escape, it can be allocated on the stack, and the memory space occupied by the object can be destroyed as the stack frame goes off the stack. This reduces the pressure on the garbage collection system. two。 Synchronization elimination: thread synchronization is relatively time-consuming, if it is determined that a variable will not escape from the thread, then there will be no competition for reading and writing of this variable, then the synchronization measures implemented on this variable can be eliminated. 3. Scalar substitution: if the escape analysis proves that an object will not be accessed externally and the object can be disassembled, then the program can actually execute without creating the object and directly creating its member variables. so it can be allocated on the stack.
However, at present, there is no guarantee that the performance benefit of escape analysis will be higher than its consumption, so this technology is not very mature.
The comparison between java and CpicCrun+ compilers the just-in-time compiler of the Java virtual machine may have some disadvantages in the output of native code compared with the static compiler of Cpicard + due to the following reasons: 1. Just-in-time compiler takes up the running time of user programs and has great time pressure, so it dares not to introduce large-scale optimization techniques casually; 2.Java language is a dynamic type-safe language, and virtualizers need to check dynamically frequently, such as null pointer, upper and lower bound ranges, inheritance relations, etc.; if virtual methods are used much more frequently in 3.Java than in C++, the frequency of polymorphic selection is much higher than that of C++. 4.Java is a language that can be extended dynamically. Loading new classes at runtime may change the original inheritance relationship, and many global optimization measures can only be done in a radical way. The object memory of 5.Java language is allocated on the heap, and the pressure of garbage collection is greater than that of C++. However, these performance disadvantages of Java language gain the advantage of development efficiency, and because all the optimization of C++ compiler is completed at compile time, the optimization measures based on run-time performance monitoring can not be carried out, which is the unique advantage of Java compiler. This is the end of how to optimize the compile time and run time of Java in JVM virtual machine. I hope the above content can be helpful to you and learn more. If you think the article is good, you can share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.