“This is the 12th day of my participation in the First Challenge 2022. For details: First Challenge 2022.”
1 introduction
The article was inspired by zhou Zhiming’s book “Deep Understanding of Java Virtual Machine 3”, which includes a section on Java security points and the pitfalls xiaomi has made.
2 brief introduction
Java SafePoint is colloquially known as a security point, and you can simply say that it records references to GC. So you need to get the addresses of objects that can be reclaimed from SafePoint during GC.
Now that the safe point has been set, it is determined that the user program execution can not stop at any point in the code instruction stream to start garbage collection, but it is mandatory that execution must reach a safe point before it can be paused.
3 of actual combat
The code above creates two threads to increment the atomic class, and because of the large number of loops, it must not have finished executing after sleeping for 1s.
So the final result should be to print out the contents first: num = xx. Then the main thread terminates, and the other two threads terminate. But the reality is often unexpected!!
As you can see from the figure above, the end result is a GC log that is eventually printed waiting for two thread loops to end.
When I changed int to long, it worked. Wow!
4 why
After a quick search at one point, the problem pops up (sewing-machine 😂😂).
Remember that safe spot above? During main thread execution, a cleanup (not necessarily a GC) is required, and it is necessary to wait for all threads to reach a safe point to obtain the address of the cleanup object.
The main thread is waiting for the safe point at the end of the int loop, so num = 200000000 is printed at the end.
So why is it okay to switch to long? Smart students have already guessed that using long will be placed in a safe spot.
5 fill blind
5.1 Selection of safety points
The selection of the safe point position is basically based on “whether it has the characteristics of long time execution of the program” as the standard for the selection.
And then someone would say, well, the number of cycles above is very large, isn’t that a long run? Unfortunately, the JVM does some of its judging by value types. Loops of ints or smaller data types are called countable loops and are not placed safely by default.
Loops with long or larger data types as index values are called uncountable loops and will be placed in safe spots.
In addition to loops, of course, things like method calls can also be placed in safe spots.
5.2 Why are These locations set as safe points
To avoid a long STW, of course. Like the problem with the code above, waiting for a long time. If it is in the c-end project of the enterprise, give you 3.25 minutes, have to say goodbye to tearful and year-end bonus!
6 Solutions
6.1 Changing the Data Type
If your loop is int, change it to long.
6.2 Increase in Cycle Period (temporary Solution)
The JVM uses SafePoints not only for GC, but also for many other operations, so it periodically stops the Java thread.
Cycle by – XX: GuaranteedSafepointInterval control, this option defaults to 1000 ms. Since the code was dormant for 1s, I made the safe point period two seconds, and the main thread printed num before it stopped at the safe point.
Note that you need to use both commands together, otherwise the JVM will not start!!
-XX:+UnlockDiagnosticVMOptions
-XX:GuaranteedSafepointInterval=2000
Copy the code
6.3 Forcibly Entering a Safety Point
The int above does not place a safe point, which is actually an optimization of the JVM. Using the -xx :+UseCountedLoopSafepoints configuration forces the JVM to turn off this optimization.
6.4 update the JDK
In JDK8, this problem persists. In other releases, such as 11 and 17, this problem has been optimized by the JVM.
7 extension
Xiaomi’s public offline HBase cluster needs to run offline tasks, but there are two threads using int, so other threads are waiting to enter SafePoint. The resulting STW time of the thread can be more than 3 seconds.
If the above are carefully read, I believe that also difficult to fall everyone.
8 Reference Article
Understanding JVM security and writing more efficient code is a great way to do it. The code that was manipulated by the JVM, “Deep Understanding the Java Virtual Machine”