Is there a cheaper method call in Java 9+ which keeps its safepoint?
The JVM removes safepoints at runtime to improve efficiency however this can make profiling and monit
In HotSpot JVM, safepoints (where the JVM can safely stop Java threads) are
All the above places, except backward branches, imply at least a method call overhead. So, apparently the cheapest way to put a safepoint is to write a non-counted loop:
public class Safepoint {
private static volatile int one = 1;
public static void force() {
for (int i = 0; i < one; i++) ;
}
}
volatile
guarantees that the loop will not be eliminated by the optimizer, and it will not be treated as counted.
I verified with -XX:+PrintAssembly
that the safepoint poll instruction is inserted wherever I call Safepoint.force()
. The call itself takes about 1 ns.
However, due to a bug in JDK 8, the existence of safepoint polls does not yet guarantee the correctness of stack traces obtained from a different thread. A native method call sets the last Java frame anchor, and thus "repairs" the stack trace. I guess this was a reason why you chose a native method. The bug was fixed in JDK 9+ though.
BTW, here is a couple of native methods that have lower overhead than Thread.holdsLock
:
Thread.currentThread().isAlive()
Runtime.getRuntime().totalMemory()
As to profiling, the safepoint-based profilers are completely broken in the first place. This is actually a reason why I started async-profiler project a few years ago. Its goal is to facilitate profiling of Java applications with low overhead and with no safepoint bias.