Dir*_*eld 3 java jvm signals stack-trace
当我向我的java进程发送SIGQUIT命令(使用kill -3或kill -QUIT)时,它会向stderr打印所有堆栈的跟踪,包含有关锁的信息和死锁检测.我能以某种方式从程序内部触发这个吗?我希望每次某个操作花费太长时间时自动执行此操作.
我知道有可能获得堆栈跟踪(请参阅是否有方法转储堆栈跟踪而不在java中抛出异常?,以线程方式转储/ JDI(Java调试器接口)).但是我希望看到所有的东西:堆栈跟踪,线程状态,持有的锁,阻塞锁,死锁检测等,即我发送SIGQUIT时得到的所有内容; 不只是堆栈跟踪.
小智 5
是的你可以.我一直在成功使用此代码来调试随机触发的并发错误:
package utils.stack;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.management.ManagementFactory;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.function.Supplier;
import javax.management.JMX;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
public interface DiagnosticCommand {
String threadPrint(String... args);
DiagnosticCommand local = ((Supplier<DiagnosticCommand>) () -> {
try {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName("com.sun.management",
"type", "DiagnosticCommand");
return JMX.newMBeanProxy(server, name, DiagnosticCommand.class);
} catch(MalformedObjectNameException e) {
throw new AssertionError(e);
}
}).get();
static void dump() {
String print = local.threadPrint();
Path path = Paths.get(LocalDateTime.now() + ".dump.txt");
try {
byte[] bytes = print.getBytes("ASCII");
Files.write(path, bytes);
} catch(IOException e) {
throw new UncheckedIOException(e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
它需要Java 8和HotSpot作为JVM,因为它模仿jstack正在做的事情,除了在同一个进程中.