Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use the just-in-time compiler in the java Hotspot virtual machine

2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces "how to use the real-time compiler in the java Hotspot virtual machine". In the daily operation, I believe many people have doubts about how to use the real-time compiler in the java Hotspot virtual machine. I have consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts about "how to use the real-time compiler in the java Hotspot virtual machine". Next, please follow the editor to study!

In some commercial virtual machines (SunHotspot, IBMJ9), Java programs are initially executed through an interpreter, and when the virtual machine finds that a method or block of code runs very frequently, it will identify the code as "hot code". In order to improve the execution efficiency of hot code, the virtual machine compiles the code into machine code related to the local platform and optimizes it at various levels. the compiler that accomplishes this task is called just-in-time compiler (JustInTimeCompiler, referred to as JIT compiler). Real-time compiler is not a necessary part of a virtual machine, but the compilation performance of real-time compiler and the degree of code optimization are one of the key indicators to measure whether a commercial virtual machine is good or bad. it is the core of the virtual machine and can best reflect the technical level of the virtual machine.

Just-in-time compiler within the Hotspot virtual machine

Key points we need to focus on solving the following issues:

Why does the Hotspot virtual machine use an architecture where interpreters and compilers coexist?

Why does the Hotspot virtual machine implement two different just-in-time compilers?

When will the program be executed using the interpreter? When to use the compiler to execute?

Which program code will be compiled into native code? How to compile to native code?

How to observe the compilation process and results of the just-in-time compiler from the outside?

Interpreter and compiler

Although not all Java virtual machines have the architecture of sampling interpreter and compiler, many mainstream virtual machines, such as SunHotspot and IBMJ9, include both interpreter and compiler. Interpreters and compilers have their own advantages: when a program needs to start quickly, the interpreter can play a role, saving compilation time and executing immediately. After the program runs, with the passage of time, the compiler gradually plays a role, after more and more code is compiled into native code, higher execution efficiency can be achieved.

When the memory resource limit of the program running environment is large, use the interpreter to save memory, on the contrary, you can use compilation to improve efficiency. At the same time, the interpreter can also be used as an "escape door" for radical optimization of the compiler, allowing the compiler to choose an optimization method that can improve the running speed most of the time according to probability. When the assumption of radical optimization is not true, for example, the type inheritance structure changes after loading a new class, and when there is a "rare trap", it can continue to execute through reverse optimization back to the interpretation state. As a result, the interpreter and compiler often work together in a virtual machine, as shown in the following figure:

Figure-interaction between interpreter and compiler

The HotSpot virtual machine has two just-in-time compilers: ClientCompiler and ServerCompiler, C1 compiler and C2 compiler for short. By default, the interpreter works directly with one of the compilers. Depending on the working mode of the virtual machine, users can use the-client parameter or-server parameter to specify the working mode of the virtual machine, and you can also use-Xint to force the virtual machine to run in "interpretation mode".

Because the just-in-time compiler takes time to compile native code, it takes longer to compile more optimized code. At the same time, the interpreter also collects performance monitoring information for the compiler, which also affects the speed of interpretation execution. In order to achieve the best balance between program startup response speed and running efficiency, HotSpot virtual machine introduces the strategy of hierarchical compilation. Hierarchical compilation is divided into different compilation levels according to the scale and time-consuming of compiler compilation and optimization, including:

Layer 0, program interpretation and execution, do not turn on performance monitoring function, can trigger layer 1 compilation.

The first layer, called C1 compilation, compiles the bytecode into native code and makes simple and reliable optimizations, adding performance monitoring logic if necessary.

Layer 2, called C2 compilation, also compiles bytecode to native code, but it takes a long time to optimize, and even makes some radical optimizations that are not entirely reliable based on performance monitoring information.

After the implementation of hierarchical compilation, ClientCompiler and ServerCompiler will work at the same time, a lot of code may be compiled many times, faster compilation speed can be obtained with ClientCompiler, better compilation quality can be obtained with ServerCompiler, and there is no need to undertake the task of collecting performance monitoring information during interpretation.

Compiled objects and trigger conditions

During the run, there are two types of hot code that will be compiled by the just-in-time compiler:

A method that is called multiple times.

The body of a loop that is executed multiple times.

In both cases, the compiler compiles the entire method. Because compilation occurs during method execution, it is vividly called OnStackReplacement (OSR for short, that is, the method is replaced while the method stack frame is still on the stack).

Determining whether a code is a hot code and whether it needs to trigger real-time compilation is called hot spot detection (HotSpotDetection). There are two main ways to detect hot spots:

Sampling-based hotspot detection: a virtual machine using this method periodically checks the top of each thread's stack, and if a method often appears at the top of the stack, it is a hot method. It has the advantages of simplicity, high efficiency, and the ability to obtain method call relationships; the disadvantage is that it is not accurate enough and is easily affected by thread blocking or other external factors.

Hot spot detection based on counting: the virtual machine using this method sets up counters for each method (even the code block). Counting the number of times the method is executed is considered a hot method if the number of times exceeds a certain threshold. This method is troublesome to implement, but its statistical results are relatively more accurate and rigorous.

The second method is used in the HotSpot virtual machine, so it has two types of counters for each method: method call counters (InvocationCounter) and backtracking counters (BackedgeCounter). In the case of determining the running parameters of the virtual machine, both counters have certain thresholds, which will trigger JIT compilation.

Compiler optimization technology

Almost all of the code optimizations made by the Java virtual machine design team are focused on the just-in-time compiler, so in general, the native code generated by the just-in-time compiler is better than the bytecode generated by javac. Next, we introduce some code optimization techniques used by the HotSpot virtual machine just-in-time compiler to generate code.

Common subexpression elimination

Common subexpression elimination is a classical optimization technique widely used in various compilers. Its principle is: if an expression E has been calculated and the values of all variables in E have not changed since the previous calculation, then the calculation of E is called common subexpression. For this kind of expression, it is no longer necessary to evaluate it, just use the previously calculated value.

Array boundary check elimination

Array boundary checking elimination is a classical language-related optimization technique in just-in-time compilers. If there is an array foo [], when the Java language accesses the array element foo [I], the system will automatically check the range of the upper and lower bounds, that is, the value range of I is 0~foo.length-1, otherwise a runtime exception java.lang.ArrayIndexOutOfBoundsException will be thrown. This is a good thing for developers, even if the programmer does not specifically write defense code, but also can avoid most overflow attacks. However, for the execution subsystem of the virtual machine, each read and write operation of array elements has an implicit conditional decision operation, which is undoubtedly a performance burden for the system with a large number of array access.

The compiler will analyze the code and remove the upper and lower bounds of the array if it is determined that a certain number of group visits will not be out of bounds. For example, when iterating to an array, the compiler can check and eliminate the upper and lower bounds of the array in the whole loop as long as the compiler determines that the value range of the loop variable must be between [0scorefoo.length) through data flow analysis.

Similar to the optimization of array boundary check elimination, there is also implicit exception handling, which is used in Java hollow pointer checking and divisor zero checking.

Method inline

Method inlining looks simple, but in practice many methods cannot be inlined directly. The reason is that in addition to private methods called by invokespecial instructions, instance constructors, parent methods, and static methods called by invokestatic instructions, there are some final methods that can only determine the version of the method to be executed at compile time, and others may have more than one version of the method receiver, which needs to be determined at run time, and this kind of method is called virtual method. Because Java language advocates object-oriented programming, and the default example method of Java language is virtual method, there is a contradiction between inline and virtual method.

For a virtual method, it is impossible to determine which version of the method should be used when inlining at compile time. In order to solve the inline problem of virtual methods, the Java virtual machine introduces a technique called "type inheritance relationship analysis" (ClassHierarchyAnalysis,CHA), which is a type analysis technology based on the whole application, which is used to determine whether an interface has more than one implementation in currently loaded classes. Information such as whether a class exists a subclass and whether the subclass is an abstract class.

A non-virtual method can be inlined directly, and it can also be inlined if it is a virtual method and there is only one version of a method through CHA analysis, but this inline belongs to "radical optimization" and needs to reserve an "escape gate", called guardian inline. If the virtual machine does not load into the class that changes the class inheritance relationship during the execution of the program, then the inline-optimized code can be used all the time. But if you load a new class that causes the inheritance relationship to change, you need to discard the compiled code, return to interpreted state execution, or recompile.

If CHA finds out that there are multiple versions of a method, the compiler will make one last effort to use the inline cache InlineCache to complete the method inline, which is a cache built before the normal entry of the target method. It works by that the inline cache is empty before the method call occurs, and when the first call occurs, the cache records the version information of the method recipient. Check the version for each subsequent execution, and if the method recipient version for each subsequent call is the same, then the inline can be used all the time, otherwise the virtual method table is found for method dispatch.

Escape analysis

Escape analysis is a cutting-edge optimization technology in Java virtual machine at present. Like type inheritance relationship analysis, it is not a technology to directly optimize code, but an analysis technology that provides a basis for other optimization methods. The basic behavior of escape analysis is to analyze the dynamic scope of an object: when an object is defined in a method, it may be referenced by an external method, such as passing it as a call parameter to other methods, called method escape. It may even be accessed by external threads, such as assigning values to class variables or instance variables accessed in other threads, called thread escapes.

If you can prove that an object does not escape outside the method or thread, you can make some efficient optimizations for this variable:

Stack allocation: Java generally allocates objects on the heap, object collection depends on the virtual machine's garbage collection system, garbage collection system takes time to recover and organize memory. If an object does not escape from the method, it would be a good idea to allocate the object on the stack. The memory space occupied by the object can be destroyed as the stack frame goes off the stack, reducing the pressure on the garbage collection system.

Synchronization elimination: thread synchronization itself is a relatively time-consuming process. If the escaping thread analysis determines that an object will not escape from the thread and will not be accessed by other threads, then there will certainly be no competition for reading and writing of this variable. synchronization measures implemented on this variable can also be eliminated.

Scalar substitution: scalar means that a data can no longer be decomposed into smaller data, and the original data types in Java can not be further decomposed, so they can be called scalars. On the other hand, if a data can continue to be decomposed, it can be called aggregate, and the object in Java is a typical aggregate. If you break up a Java object, it is called scalar substitution to restore its member variables to the original type according to the access of the program. If the escape analysis proves that an object will not be accessed externally, and the object can be disassembled, then when the program is actually executed, it may not create the object, but directly create several of its member variables instead. After splitting the object, in addition to allowing member variables to be assigned and read-write on the stack, you can also create conditions for further optimization.

It is necessary to pay attention to whether the performance benefit of escape analysis is lower than its consumption. If you want to judge whether an object will escape completely and accurately, you need to carry out a series of complex analyses that are sensitive to data flow, so as to determine the impact of each branch of the program on this object, which is a relatively time-consuming process. If the analysis finds that there are few objects that do not escape, then the time spent in these runs will be wasted, so at present virtual machines can only use less accurate But the algorithm with relatively low time pressure is used to complete the escape analysis.

At this point, the study on "how to use the just-in-time compiler in the java Hotspot virtual machine" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

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.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report