以编程方式触发完整的堆栈转储?

2023-08-23Java开发问题
1

本文介绍了以编程方式触发完整的堆栈转储?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

当我向我的 java 进程发送 SIGQUIT 命令时(使用 kill -3 或 kill -QUIT ),它会将所有堆栈的跟踪打印到 stderr,其中包含有关持有的锁和死锁检测的信息.我可以从程序内部以某种方式触发它吗?我想在每次某个操作花费太长时间时自动执行此操作.

When I send a SIGQUIT command to my java process (using kill -3 or kill -QUIT ), it prints a trace of all stacks to stderr, with information about locks held, and deadlock detection. Can I trigger this from inside the program somehow? I want to do this automatically every time a certain operation takes too long.

我知道可以获得堆栈跟踪(请参阅 有没有办法在不抛出异常的情况下转储堆栈跟踪?, 线程转储程序/JDI(Java调试器接口)).但我想查看所有内容:堆栈跟踪、线程状态、持有的锁、阻塞的锁、死锁检测等,即我发送 SIGQUIT 时得到的所有内容;不仅仅是堆栈跟踪.

I know it's possible to get a stack trace (see Is there a way to dump a stack trace without throwing an exception in java?, Thread dump programmatically /JDI (Java Debugger Interface)). But I want to see the whole everything: stack traces, thread states, locks held, locks blocked on, deadlock detection, etc., i.e. everything I get when I sent a SIGQUIT; not just the stack trace.

推荐答案

是的,你可以.我一直在成功地使用此代码调试随机触发的并发错误:

Yes you can. I've been using this code successfully to debug randomly triggered concurrency bugs:

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);
        }
    }
}

它需要 Java 8 和 HotSpot 作为 JVM,因为它模仿 jstack 正在做的事情,除了在同一个进程中.

It requires Java 8 and HotSpot as the JVM as it mimics what jstack is doing, except from within the same process.

这篇关于以编程方式触发完整的堆栈转储?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

The End

相关推荐

如何使用 JAVA 向 COM PORT 发送数据?
How to send data to COM PORT using JAVA?(如何使用 JAVA 向 COM PORT 发送数据?)...
2024-08-25 Java开发问题
21

如何使报表页面方向更改为“rtl"?
How to make a report page direction to change to quot;rtlquot;?(如何使报表页面方向更改为“rtl?)...
2024-08-25 Java开发问题
19

在 Eclipse 项目中使用西里尔文 .properties 文件
Use cyrillic .properties file in eclipse project(在 Eclipse 项目中使用西里尔文 .properties 文件)...
2024-08-25 Java开发问题
18

有没有办法在 Java 中检测 RTL 语言?
Is there any way to detect an RTL language in Java?(有没有办法在 Java 中检测 RTL 语言?)...
2024-08-25 Java开发问题
11

如何在 Java 中从 DB 加载资源包消息?
How to load resource bundle messages from DB in Java?(如何在 Java 中从 DB 加载资源包消息?)...
2024-08-25 Java开发问题
13

如何更改 Java 中的默认语言环境设置以使其保持一致?
How do I change the default locale settings in Java to make them consistent?(如何更改 Java 中的默认语言环境设置以使其保持一致?)...
2024-08-25 Java开发问题
13