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 understand the real-time compilation and optimization technology of JIT in JVM

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

Share

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

This article introduces you how to understand the JIT real-time compilation and optimization technology in JVM, the content is very detailed, interested friends can refer to, I hope it can be helpful to you.

The difference between JVM Client mode and Server mode

Through java-version, you can see which mode JVM is in, and you can configure it by modifying the configuration file, so what's the difference?

When Server:-Server mode starts, it is slower, but after startup, the performance is higher, so it is suitable for running server daemon.

When Client:-Client mode starts, it is faster, and after startup, it is not as good as Server, so it is suitable for desktop and other programs with interface.

Hotspot code

Understand

When a virtual machine discovers that a method or block of code is running very frequently, it identifies the code as "hot code".

Classification of hotspot codes

A method that is called many times

If a method is called more often, the code in the method body will be executed more times, and it is only natural to become a "hot code".

The body of a loop that is executed many times

A method has only been called once or a few times, but there is a loop body with a large number of loops inside the method body, so the code of the loop body is also repeated many times, so the code should also be regarded as "hot code".

The number of times mentioned above is an unspecific word, so how many times does it take to become a hot code?

How to detect hotspot codes

To determine whether a code is a hot code and whether it needs to be triggered even if it is compiled is called hot spot detection. Hot spot detection does not necessarily know how many times the method has been called. At present, there are two main hot spot detection methods:

Sampling-based hotspot detection: a virtual machine using this method periodically checks the top of each thread's stack if it is found that one (or some) method often appears at the top of the stack, then this method is a "hot method"

Advantages: the implementation is simple and efficient, and it is easy to obtain the method call relationship (just expand the call stack)

Disadvantages: inaccurate, easy to disrupt hot spot detection due to thread blocking or other external factors

Counter-based hot spot detection: a virtual machine using this method sets up a counter for each method (or even a code block) and counts the number of times the method is executed. If the number of times exceeds a certain threshold, it is considered a "hot method".

Advantages: the statistical results are accurate and rigorous

Disadvantages: it is troublesome to implement, it is necessary to establish and maintain counters for each method, and the calling relationship of the method cannot be obtained directly.

HotSpot uses the second, counter-based hotspot detection method.

Determine the way to detect hot code, how to calculate the specific number of times?

Types of counters (two kinds of collaboration)

Method call counter: this counter is used to count the number of times a method has been called. The default threshold is 1500 in Client mode and 10000 in Server mode

Back counter: count the number of times the loop body code is executed in a method

What's the use of knowing the hotspot codes and counters? Reaching the threshold of the counter will trigger the just-in-time compilation explained later, that is, just-in-time compilation needs to meet certain conditions before it will be triggered. Write the conclusion first, and then explain what the just-in-time compiler is.

The collaboration of two counters (this is the case of method call counters): when a method is called, it is checked to see if there is a version compiled by JIT (explained later), and if so, the compiled native code is preferred for execution. If there is no compiled version, increase the call counter of this method by 1, and then determine whether the sum of the method call counter and the backside counter exceeds the threshold of the method call counter. If the threshold has been exceeded, a code compilation request for this method is submitted to the just-in-time compiler.

When the compilation is complete, the call entry address of the method is automatically changed by the system to the new one, and the compiled version is used the next time the method is called.

Bytecode, machine code, native code?

Bytecode refers to the commonly known .class file, and Java code is compiled into bytecode through the javac command.

Both machine code and local code mean that the machine can directly recognize the running code, that is, machine instructions.

Bytecode cannot be run directly and needs to be interpreted or compiled into machine code by JVM before it can be run.

At this point, you have to ask, why doesn't Java compile directly into machine code? isn't that faster?

1. Machine code is platform-related, that is, operating system-related. Different operating systems can recognize different machine codes. If it is compiled into machine code, it is almost the same as C and C++, and cannot be cross-platform. Java does not have the loud slogan "compile once, run everywhere".

two。 The reason for not compiling all at once is that some code is only run once, so there is no need to compile, just explain and run it directly. And those "hot" code, repeated interpretation must be very slow, JVM in the process of running the program is constantly optimized, using the JIT compiler to compile those hot code, so that they do not have to explain and execute sentence by sentence every time

3. Another reason is the coexistence of the interpreter and the compiler explained later.

What is JIT?

In order to improve the execution efficiency of hot code, at run time, the virtual machine will compile the code into machine code related to the local platform and optimize it at various levels. The compiler that accomplishes this task is called just-in-time compiler (Just In Time Compiler), or JIT compiler for short.

What is compilation and interpretation?

Compiler: every statement of the source program is compiled into a machine language and saved as a binary file, so that the computer can run the program directly in the machine language at run time.

Interpreter: only when the program is executed, it is interpreted one by one into machine language for the computer to execute, so the running speed is not as fast as the compiled program.

Through the javac command, the source code of the Java program is compiled into Java bytecode, which is what we often call class files. This is what we usually understand as compilation.

Bytecode is not a machine language, and bytecode needs to be translated into machine instructions for the machine to execute. This process is done by the Java virtual machine, which is also called compilation. It's a deeper compilation. (in fact, it is an explanation, and there is also compilation after the introduction of JIT)

Now there is a doubt, isn't Java interpreting and executing?

Yes, Java needs to translate bytecode into corresponding machine instructions and execute them one by one. This is the function of the traditional JVM interpreter. It is precisely because the interpreter is inefficient to translate and execute this process one by one, the JIT just-in-time compilation technology is introduced.

It must be pointed out that whether it is interpreted or compiled, the final unit of code executed is machine code, or native code, that can be run directly on a real machine.

Attach a picture to understand

Why do HotSpot virtual machines use an architecture where interpreters and compilers coexist?

Both interpreter and compiler have their own advantages

Interpreter: when a program needs to be started and executed quickly, the interpreter can play a role first, saving compilation time and executing immediately.

Compiler: after the program runs, over time, the compiler gradually plays a role, after compiling more and more code into native code, you can achieve higher execution efficiency.

Cooperation between the two: when memory resources are limited in the program running environment, interpretive execution can be used to save memory, while compiler execution can be used to improve efficiency. When it is optimized by the compiler, it is found that it does not play an optimization role, and you can continue to execute it by going back to the interpreted state by reverse optimization.

The relationship between just-in-time compiler and Java virtual machine

The just-in-time compiler is not a necessary part of the virtual machine, and the Java virtual machine specification does not stipulate that there must be a real-time compiler in the Java virtual machine, let alone limit or guide how the real-time compiler should be implemented.

However, the compilation performance of the real-time compiler and the degree of code optimization are one of the key indicators to measure whether a commercial virtual machine is excellent or not. It is also the core part of the virtual machine and can best reflect the technical level of the virtual machine.

Classification of just-in-time compilers

Client Compiler-C1 compiler

Server Compiler-C2 compiler

At present, the mainstream HotSpot virtual machines (JDK1.7 and previous versions of virtual machines) work directly with an interpreter and one of the compilers. Which compiler the program uses depends on the running mode of the virtual machine, which are the two modes mentioned at the beginning of the article.

In HotSpot, the interpreter and the JIT just-in-time compiler exist at the same time, they are two components of JVM. For different types of applications, users can flexibly choose whether to run based on the interpreter or the JIT compiler according to their own characteristics and needs. HotSpot provides users with several running modes to choose from, which can be set by parameters, namely: interpretation mode, compilation mode, mixed mode, HotSpot default is mixed mode, it should be noted that the compilation mode is not compiled entirely through JIT, but the compiler mode is preferred to execute the program, but the interpreter still has to intervene in the execution process when the compilation cannot be carried out.

Hierarchical compilation

Cause: because the just-in-time compiler takes time to compile native code, it may take longer to compile more optimized code; and to compile more optimized code, the interpreter may also collect 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, the HotSpot virtual machine enables 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.

Layer 0: program interpretation and execution, the interpreter does not turn on the performance monitoring function, and layer 1 compilation can be triggered.

Layer 1: also known as C1 compilation, compiles bytecode into native code for simple, reliable optimization, and adds performance monitoring logic if necessary.

Layer 2 (or above): also known as C2 compilation, also compiles bytecode to native code, but enables 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, Client Compiler and Server Compiler will work at the same time, and a lot of code may be compiled many times, using Client Compiler to get higher compilation speed, Server Compiler to get better compilation quality, and no longer have to undertake the task of collecting performance monitoring information during interpretation and execution.

Compiler optimization technology

There is a consensus among Java programmers that it is faster to execute native code in compiled mode than in interpretive mode. In addition to the extra time consuming when the virtual machine interprets and executes bytecode, another important reason is that the virtual machine design team focuses almost all the optimization measures on the code in the just-in-time compiler, so generally speaking. The native code generated by the just-in-time compiler is better than the bytecode generated by javac. The following are the code optimization techniques used by the just-in-time compiler of a typical HotSpot virtual machine to generate code:

One of the classical language-independent 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 the occurrence of E becomes a common subexpression. For this kind of expression, there is no need to take the time to evaluate it, just directly use the result of the previously calculated expression instead of E.

Example: int d = (cymb) * 12 + a + (a + bauc)-> int d = E * 12 + a + (a + E)

One of the classical optimization techniques related to language: array range checking and elimination

When accessing array elements in the Java language, the system will automatically check the range of the upper and lower bounds, and an exception will be thrown beyond the boundary. For the execution subsystem of the virtual machine, each read and write of array elements has an implicit conditional decision operation, which is undoubtedly a performance burden for program code with a large number of array access. According to the data flow analysis, Java can determine the scope and eliminate the upper and lower bound check during the compilation period, thus saving many conditional judgment operations.

One of the most important optimization techniques: method inlining

It is simply understood as "copying" the code of the target method into the method that initiates the call, eliminating some useless code. It's just that the inline process in the actual JVM is very complex and will not be analyzed here.

One of the most advanced optimization techniques: escape analysis

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 calling 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 that can be accessed in other threads, called thread escapes.

If it can be proved that an object will not escape outside the method or thread, that is, other methods or threads cannot access the object in any way, some efficient optimizations can be made for this variable:

Stack allocation: assign local objects that will not escape to the stack, and the objects will be automatically destroyed with the end of the method, reducing the pressure on the garbage collection system.

Synchronization elimination: if this variable does not have thread escape, that is, it cannot be accessed by other threads, then there is no competition for reading and writing to this variable, and synchronization measures can be eliminated (synchronization comes at a price)

Scalar substitution: scalars refer to data types that cannot be decomposed, such as primitive data types and reference types. The aggregate amount can continue to be decomposed, such as objects in Java. Scalar substitution if an object will not be accessed externally and the object can be disassembled, the actual execution may not create the object, but several of the member variables used by this method may be replaced by directly creating it. This approach not only allows the member variables of the object to be assigned and read-write on the stack, but also creates conditions for subsequent further optimizations.

On how to understand the JVM JIT real-time compilation and optimization technology to share here, I hope that the above content can be of some help to you, can learn more knowledge. 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.

Share To

Internet Technology

Wechat

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

12
Report