我知道以下在 java 中生成线程转储的方法:
在这些方法中,哪种方法对 JVM 的性能影响最小?
最佳答案
如果您只需要将所有堆栈跟踪转储到标准输出,kill -3
和 jstack
应该是最便宜的。该功能在 JVM 代码中本地实现。没有创建中间结构 - VM 在遍历堆栈时自行打印所有内容。
除了信号处理程序在本地将堆栈跟踪打印到 Java 进程的标准输出之外,这两个命令执行相同的 VM 操作,而 jstack
通过 IPC(Linux 上的 Unix 域套接字或 Windows 上的命名管道)接收来自目标 VM 的输出。jstack
用途 Dynamic Attach引擎盖下的机制。如果您希望以纯字节流的形式接收堆栈跟踪,您也可以直接使用动态附加。
import com.sun.tools.attach.VirtualMachine;
import sun.tools.attach.HotSpotVirtualMachine;
import java.io.InputStream;
public class StackTrace {
public static void main(String[] args) throws Exception {
String pid = args[0];
HotSpotVirtualMachine vm = (HotSpotVirtualMachine) VirtualMachine.attach(pid);
try (InputStream in = vm.remoteDataDump()) {
byte[] buf = new byte[8000];
for (int bytes; (bytes = in.read(buf)) > 0; ) {
System.out.write(buf, 0, bytes);
}
} finally {
vm.detach();
}
}
}
请注意,所有提到的方法无论如何都在 VM 安全点中运行。这意味着在收集堆栈跟踪时所有 Java 线程都将停止。
关于performance - 哪种方法在 java 中生成线程转储最不显眼?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26795573/