java - 从特定线程请求堆栈跟踪是否需要所有线程都处于安全点?

标签 java performance profiling jvmti

当通过 Thread#getStackTrace()ThreadMXBean#getThreadInfo(long[], int) 从另一个线程请求堆栈跟踪时,是否所有线程都必须输入一个安全点,因此必须等到所有其他线程都进入安全点?

This blog似乎暗示是这样的:

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.)

这意味着从单个线程获取堆栈跟踪与获取所有堆栈跟踪一样具有侵入性(就由于全局安全点命中频率增加而导致的高开销而言)。

但这对 OpenJDK 来说实际上/仍然如此吗?您是否有关于为什么会这样或相关源代码的任何指示?

最佳答案

在 OpenJDK 中(直到当前的 JDK 13)Thread.getStackTrace() 仍然在全局 stop-the-world 安全点运行:

Thread.java

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

这下降到 ThreadService::dump_stack_traces ,它执行 VM_ThreadDump VM 线程中的操作。所有 VM_* 操作都用于在全局安全点运行。

JEP 312: Thread-Local Handshakes在 JDK 10 中引入,提供了每线程安全点机制。现在VM_Handshake及其所有后代都不需要全局安全点:

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

但是,VM_ThreadDump 不是这样的操作。 VM_GetStackTrace 也不是用于实现JVM TI GetStackTrace函数。

有一个 Unresolved 问题 JDK-8201641将来某个时间利用线程本地握手获取单个线程的堆栈跟踪。

关于java - 从特定线程请求堆栈跟踪是否需要所有线程都处于安全点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59171277/

相关文章:

java - 如何在android xml文件和java文件中显示/隐藏TextView?

java - 如何获取 JDBC 查询的执行/获取时间?

c - 使用 OpenMP 和 PThreads 的并行程序比顺序程序慢

c# - 如何拦截来自应用程序的 HTTP 调用?

java - Hibernate:如何根据特定条件从另一个实体获取或加载惰性实体?

java - HTTPS 上的文件流速度很慢

java - 根据条件不同的覆盖方法

android - 如何将 Bango SDK 添加到我的 android 项目中?

c++ - C++ 枚举使用起来比整数慢吗?

java - 在 Mac 上分析 Java 中的 CPU 使用情况