哪种方法在java中生成线程转储最不突兀?

Ove*_*esh 5 performance jvm thread-dump

我知道在java中生成线程转储的以下方法:

  • 杀-3
  • jstack
  • 来自JVM内部的JMX
  • JMX遥控器
  • JPDA(远程)
  • JVMTI(C API)

这些方法对JVM的性能影响最小?

apa*_*gin 8

如果你只需要将所有堆栈跟踪转储到stdout,kill -3并且jstack应该是最便宜的.该功能在JVM代码中本机实现.没有创建中间结构 - VM在遍历堆栈时自行打印所有内容.

两个命令执行相同的VM操作,除了信号处理程序在本地将堆栈跟踪打印到Java进程的stdout,同时jstack通过IPC(Linux上的Unix域套接字或Windows 上的命名管道)接收目标VM的输出.

jstack在引擎盖下使用动态连接机制.如果希望将堆栈跟踪作为普通字节流接收,也可以直接使用动态连接.

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,无论如何,所有提到的方法都在VM安全点中运行.这意味着在收集堆栈跟踪时,所有Java线程都会停止.


小智 0

性能最佳的选项可能是使用 ThreadMXBean.dumpAllThreads() API,而不是请求将文本线程转储写入磁盘: http ://docs.oracle.com/javase/7/docs/api/java/lang /management/ThreadMXBean.html#dumpAllThreads(boolean,%20boolean)

当然,是否可以使用它取决于您是否需要线程转储文件,或者只是数据。