Differences between JVM Client mode and Server mode



Java-version allows you to see which mode the JVM is in, and you can configure it by modifying the configuration file. What’s the difference?

Server: – When the Server mode is started, the speed is slow, but after the Server mode is started, the performance is higher, and it is suitable for running Server background programs

Client: – The Client mode is faster than the Server mode. It is suitable for desktop applications with interfaces

Hot code

understand

When the virtual machine finds that a method or block of code is being run particularly frequently, it identifies that code as “hot code.”

Classification of hot code

  • A method that is called multiple times


  • The body of a loop that is executed multiple times

A method is called only once or a small number of times, but there are more loops inside the method body, so the code in the loop body is executed more than once, so it should also be considered “hot code.”

Multiple is a non-specific word, but how many times does it take to become hot code?

How do I detect hot codes

Hotspot detection is the behavior of determining whether a piece of code is hotspot code and whether it needs to trigger even compilation. Hotspot detection does not necessarily know how many times the method is called. There are two main methods for determining hotspot detection at present:

  • Sample-based hot spot detection: A virtual machine that uses this method periodically checks the top of the stack of each thread. If a method (or methods) appears frequently at the top of the stack, it is a “hot spot method.”

Disadvantages: imprecise, easily disrupted by thread blocking or other external factors

  • Counter based hot spot detection: A virtual machine that takes this approach sets up counters for each method (even a block of code), counts the number of times a method is executed, and considers it a “hot method” if it exceeds a certain threshold

Advantages: accurate and rigorous statistical results

Disadvantages: Cumbersome implementation, need to establish and maintain counters for each method, can not directly obtain the method call relationship

HotSpot uses the second, counter – based approach to HotSpot detection.

Once you’ve determined how to detect hot code, how do you count the number of times?

Types of counters (both work together)

  • Method call counter: This counter counts the number of times a method is called. The default threshold is 1500 times in Client mode and 10000 times in Server mode
  • Loopback counter: Counts the number of times loop body code is executed in a method
What is the use of knowing hotspot codes and counters? Reaching the threshold of a counter triggers just-in-time compilation, which requires certain conditions to be met.


Collaboration between two counters (in the case of method call counters) : When a method is called, it is checked to see if a JIT-compiled version of the method exists, and if so, it is executed using compiled native code in preference. If no compiled version exists, the method’s call counter is incremented by one, and the method call counter plus the back side counter exceeds the method call counter threshold. If the threshold is exceeded, a code compilation request for the method is submitted to the just-in-time compiler.

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

What is bytecode, machine code, native code?

Bytecodes are commonly known as.class files. Java code is compiled into bytecodes using javac commands

Both machine code and native code refer to running code that the machine can recognize directly, namely machine instructions

Bytecodes cannot be run directly and need to be interpreted by the JVM or compiled into machine code to run

At this point, you ask, why isn’t Java compiled directly to machine code, which is faster?

1. Machine code is platform-dependent, that is, operating system dependent, different operating systems can recognize different machine code, if compiled into machine code is not like C, C++, cross-platform, Java does not have the loud slogan “compile once, run everywhere”;

2. The reason for not compiling all at once is that some code is run only once. There is no need to compile. The “hot” code, interpreted repeatedly, must be slow, and the JVM optimizes it as it runs, using a JIT compiler to compile it so that it doesn’t have to be interpreted every time;

3. Another reason is the coexistence of interpreters and compilers, as described below.

What is JIT?

To improve the efficiency of hot code execution, the virtual machine compiles the code into local platform-specific machine code and performs various levels of optimization at run Time with a Compiler called Just In Time Compiler, or JIT Compiler

What is compilation and interpretation?

Compiler: every statement of the source program is compiled into machine language, and saved into binary files, so that the computer can run this program directly in machine language, very fast;

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

The source code of a Java program is compiled into Java bytecodes, commonly known as class files, through the Javac command. This is compilation in the usual sense.

Bytecode is not a machine language, and in order for the machine to be able to execute it, it needs to be translated into machine instructions. This process is done by the Java virtual machine and is also called compilation. It’s deeper compilation. (Actually interpretation, compilation also exists after JIT is introduced)

At this point there is confusion, Java is not interpreted execution?

Yes, Java needs to translate bytecode into the corresponding machine instructions and execute them, which is what traditional JVM interpreters do, and it is the inefficiency of interpreters to translate and execute this process that introduced JIT just-in-time compilation.

It is important to note that the unit of code that is ultimately executed, whether interpreted or compiled, is machine code, or native code, that can be run directly on the real machine

Attached is a picture to understand



Compilation principle of reference: [in-depth analysis of the Java compiler principle] (www.hollischuang.com/archives/23)…

Why does the HotSpot VIRTUAL machine use an interpreter and compiler architecture?

Both the interpreter and the compiler have their advantages

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

Compiler: After a program runs, the compiler gradually comes into play as time goes by. More and more code is compiled into local code to achieve higher execution efficiency.

Collaboration between the two: interpreted execution can be used to save memory when memory resources are limited in the program environment, while compiled execution can be used to improve efficiency. When optimizing through the compiler, it is found that no optimization effect is played, and can be returned to the explain state to continue executing through inverse optimization.

The just-in-time compiler versus the Java Virtual machine

Just-in-time compilers are not a necessary part of the virtual machine, and the Java Virtual Machine specification does not stipulate that just-in-time compilers must exist in the Java Virtual machine, nor does it limit or guide how just-in-time compilers should be implemented.

However, real-time compiler compilation performance and code optimization degree is one of the most critical indicators to measure the excellence of a commercial virtual machine. It is also the most core part of the VIRTUAL machine and most reflects the technical level of the virtual machine.

Classification of just-in-time compilers

  • Client Compiler – C1 Compiler
  • Server Compiler – C2 Compiler

By default, HotSpot virtual machines (JDK1.7 and earlier) work directly with one interpreter and one compiler, depending on the mode in which the machine is running, the two modes mentioned at the beginning of this article.


In HotSpot, the interpreter and JIT just-in-time compiler exist together as two components of the JVM. For different types of applications, users have the flexibility to choose whether to run based on an interpreter or a JIT compiler, depending on their characteristics and needs. HotSpot provides the user with several operating modes to choose from, with the following parameters: Interpret mode, compile mode, and Hybrid mode. HotSpot is a hybrid mode by default. Note that compilation mode is not all JIT compilation, but compilation is preferred, but the interpreter still has to step in if compilation is not possible.

Layered compilation

Cause: Since just-in-time compilers take time to compile native code, it may take longer to compile more optimized code. In order to compile more optimized code, the interpreter may have to collect performance monitoring information for the compiler, which also has an impact on the speed of interpretation execution. In order to achieve the best balance between application startup responsiveness and runtime efficiency, the HotSpot VIRTUAL machine enables a tiered compilation strategy

Hierarchical compilation Is divided into different compilation levels according to the scale and time of compilation and optimization by the compiler:

  • Layer 0: program interpretation executes. The interpreter does not enable performance monitoring function, triggering layer 1 compilation.
  • Level 1: also known as C1 compilation, bytecode is compiled into native code for simple, reliable optimizations, including performance monitoring logic if necessary.
  • Layer 2 (or above) : also known as C2 compilation, this also compiles bytecode to native code, but with some optimizations that take longer to compile and even make unreliable aggressive optimizations based on performance monitoring information.

After implementing hierarchical compilation, Client Compiler and Server Compiler will work at the same time, and a lot of code may be compiled multiple times. Using Client Compiler can obtain higher compilation speed, while using Server Compiler can obtain better compilation quality. There is no need to collect performance monitoring information when interpreting execution.


Compiler optimization technique

Java programmers have a consensus, executing native code compilation way faster than interpreted execution way, there are such consensus, remove the virtual machine to explain the reason of extra time-consuming when performing a bytecode, there is another important reason is that the virtual machine design team almost all of the code optimization measures were focused on the real-time compilers, so in general, Native code generated by the just-in-time compiler is better than bytecode generated by javac. Here are some code optimization techniques used by the just-in-time compiler for a representative HotSpot VIRTUAL machine to generate code:

  • One of the classic optimization techniques for language independence is common subexpression elimination

If an expression E has been evaluated, and the values of all variables in E have not changed since the previous evaluation, then the occurrence of E becomes a common subexpression. For this expression, there is no need to spend time evaluating it, just replace E with the result of the previously evaluated expression. Example: int d = (c*b) * 12 + a+ (a+ b * c) -> int d = E * 12 + a+ (a+ E)

  • One of the classic language-related optimization techniques: array range checking elimination

When accessing an array element in the Java language, the system automatically checks the range of the upper and lower bounds, and throws an exception if the bounds are exceeded. For the execution subsystem of the virtual machine, each read or write to an array element carries an implicit conditional operation, which can be a performance burden for program code with a large number of array accesses. Java can determine the scope according to the data flow analysis at compile time, thus eliminating the upper and lower bounds checking and saving multiple condition judgment operations.


  • One of the most important optimization techniques: method inlining

The simple idea is to “copy” the target method’s code into the calling method, eliminating some useless code. However, the inline process in a real JVM is complex and will not be analyzed here.


  • One of the most cutting-edge optimization techniques: escape analysis

The basic behavior of escape analysis is analyzing object dynamic scope: 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 another method, called
Method escape.It may even be accessed by an external thread, such as an instance variable assigned to a class variable or accessible from another thread, called
Thread escape.

If you can prove that an object cannot escape from a method or thread, that is, no other method or thread can access the object in any way, then you can make some efficient optimizations for this variable:

  • Stack allocation: Assign local objects that do not escape to the stack, and that object is automatically destroyed at the end of the method, reducing the stress on the garbage collection system.
  • Synchronization elimination: If the variable does not escape, i.e. cannot be accessed by other threads, then there is no contention for reading or writing the variable and synchronization can be eliminated (synchronization comes at a cost)
  • Scalar substitution: A scalar is a data type that cannot be decomposed, such as the original data type and reference type. Aggregations are things that can be further decomposed, such as objects in Java. Scalar substitution If an object cannot be accessed externally and the object can be split, the actual execution may not create the object, but instead create its member variables that are used by the method. This approach not only allows the object’s member variables to be allocated and read and written on the stack, but also creates conditions for further optimization.


Arrange by oneself understanding, knowledge point order does not know whether appropriate, still ask everybody to guide.


Reference:

In-depth Understanding of the Java Virtual Machine

www.hollischuang.com/archives/23…