javaperformanceprofilingjvmti

Does requesting a stack trace from a particular thread require all threads to be at a safe point?


When requesting the stack trace from another thread via Thread#getStackTrace() or ThreadMXBean#getThreadInfo(long[], int), do all threads have to enter a safe point and thus have to wait until all other threads have entered a safe point?

This blog seems to suggest that this is the case:

You hit a global safepoint whether you are sampling a single thread or all threads (at least on OpenJDK, Zing is slightly different but as a profiler vendor OpenJDK is your assumption.)

That would mean that it would be just as intrusive (in terms of high overhead due to an increased frequency of global safe point hits) to get the stack track from a single thread than it is to get all stack traces.

But is that actually/still true for OpenJDK? Do you have any pointers to why that is or to the relevant source code?


Solution

  • In OpenJDK (up to current JDK 13) Thread.getStackTrace() still runs at the global stop-the-world safepoint:

    Thread.java

    public StackTraceElement[] getStackTrace() {
        if (this != Thread.currentThread()) {
            ....
            StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this});
    

    This goes down to ThreadService::dump_stack_traces, which executes VM_ThreadDump operation in a VM thread. All VM_* operations used to run at the global safepoint.

    JEP 312: Thread-Local Handshakes introduced in JDK 10, provides a per-thread safepoint mechanism. Now VM_Handshake and all its descendants do not require a global safepoint:

    class VM_Handshake: public VM_Operation {
      const jlong _handshake_timeout;
     public:
      bool evaluate_at_safepoint() const { return false; }
    

    However, VM_ThreadDump is not such an operation. Neither is VM_GetStackTrace used to implement JVM TI GetStackTrace function.

    There is an open issue JDK-8201641 to make use of thread-local handshakes to get a stack trace of a single thread some time in future.