Safepoint, also known as a security point, is an important concept in JVMS such as hotspot. Here’s a partial look at what SafePoint is, what It does, how safePoint is implemented, and what you should be aware of as a developer.

What is safepoint

The JVM’s main job is to execute Java programs, and the JVM runtime itself is a program, but the JVM has a lot of ancillary work to execute Java programs, such as GC, JIT compilation, and so on. User Java programs running on the JVM are commonly referred to as mutators.

In GC, for example, the JVM GC are commonly use accessibility analysis, namely from the application of some GC Root (such as a running thread method in the stack frame of the local variables and reference, static variable references, etc.) in the operating table by reference to reference graph traversal, if in the process of the JVM traversal mutator at work, too, The Mutator may modify the reference relationship of the object graph, and if the JVM does not take special care of this concurrent modification, it may result in some non-recyclable objects not being traversed, thus being marked as garbage objects and incorrectly collected.

The IMPLEMENTATION cost of the JVM is high if the GC is to be fully concurrent, and in many cases the overall throughput is reduced. (Think of the cas atomic operation and the use of locking in concurrent programming. If the competition is fierce, the use of locking is more efficient, because it can reduce the CPU consumption of cas cycle.)

Therefore, many GC collectors have some StopTheWorld phase, which is SafePoint. There are no mutator manipulation objects in SafePoint, and the data type for each location in the thread stack and heap is determined (such as whether an 8-bit piece of data is a long or an object reference).

A thread is either in SafePoint or not in SafePoint. The StopTheWorld mentioned above refers to global SafePoint (for Hotspot), which requires all threads to be in safePoint state. Safepoint also refers to global SafePoint unless otherwise specified.

How is SafePoint implemented

How does the JVM notify threads to enter SafePoint

Safepoint is collaborative in its hotspot implementation. When the JVM needs a Mutator to enter SafePoint, it sets a status flag indicating that safepoint is ready to enter. Each Mutator thread checks this status flag at the appropriate time. Suspends itself if it finds it needs to enter SafePoint. The right timing here is not to be so frequent as to avoid increasing runtime overhead (not every step), but also not to go too long without checking to avoid entering SafePoint too slowly (it takes all the threads to enter SafePoint state). If one thread keeps working without checking SafePoint, it will affect the other threads because they are waiting. If there is Compiled code, the JIT inserts check code in certain places, such as where method calls return and loops jump back. With interpreted code, the JVM has two bytecode tables, and if it needs to enter SafePoint, the JVM switches to the table with safePoint status checks.

How do threads check to enter SafePoint

To minimize overhead, safePoint status checking in Hotspot is implemented by reading a memory value, and if you need to enter SafePoint, setting the memory page to be protected, which triggers a Page fault and allows you to enter SafePoint through exception handling. This is much lighter than accurately reading a memory value (such as Boolean data) because memory synchronization is required. You might think that if a thread is in a sleep

Threads are also in SafePoint when executing JNI code, and other “blocked” states, such as Thread.sleep, are also in SafePoint. This prevents a thread in sleep state from suddenly running after another thread has entered SafePoint.

What could trigger safePoint

In addition to some GC phases that need to be performed within SafePoint, other common operations are.

  • Revoke bias(if frequent bias locks are seen, consider disabling bias locks -XX: -usebiasedlocking)
  • Dump Thread stack, whether through jstack or through JMX ThreadMXBean. GetThreadInfo (maxDepth > 0) or Thread. The methods of getAllStackTraces, will trigger safepoint, A very large number of threads can result in a long pause
  • Class redefinition(Retransform or define a class by Instrument object)
  • code deoptimization
  • There are many other operations

How do I troubleshoot SafePoint problems

Add some parameters to the JVM startup parameters to print out application pause and SafePoint information. If version <=jdk8

-XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount=1

Copy the code

If version > JDK8

-Xlog:gc*=info::time,tags,tid -Xlog:safepoint=info::time,tags,tid

Copy the code

A sample

[the 2020-05-18 T09:18:55. 978-0800] [19459] [safepoint] Application time: 1.0038747 seconds [2020-05-18T09:18:55.978-0800][19459][SafePoint] Entering safepoint region: ThreadDump [2020-05-18T09:18:55.980-0800][19459][Safepoint] Leaving Safepoint Region [2020-05-18T09:18:55.980-0800][19459][Safepoint] Total time for which Application threads were stopped: 0.0017502 seconds, Stopping Threads took: 0.0000312 secondsCopy the code

This means that after 1.0038747 seconds, the application thread was suspended for 0.0017502 seconds as ThreadDump began to enter SafePoint. It took 0.0000312 seconds to suspend these threads

Resources

  • Psy-lob-saw.blogspot.com/2015/12/saf…
  • Psy-lob-saw.blogspot.com/2014/03/whe…
  • Blog. Ragozin. Info / 2012/10 / saf…
  • Hg.openjdk.java.net/jdk8/jdk8/h…
  • Stackoverflow.com/questions/1…
  • www.kernel.org/doc/Documen…

This article uses the article synchronization assistant to synchronize