【问题标题】:Is there a way to trigger a jvm thread dump on an Oracle exception?有没有办法在 Oracle 异常上触发 jvm 线程转储?
【发布时间】:2011-12-13 19:41:44
【问题描述】:

我们有一个在 Websphere 中运行的 Java 程序,它使用一个使用直接 jdbc(没有 Hibernate 或 JPA)的 Oracle 数据库。我们的客户正在使用 HP Performance Center 进行负载测试,他在负载下偶尔会遇到 Oracle“死锁”异常

Caused by: java.sql.SQLException: ORA-00060: deadlock detected while waiting for resource

有没有办法,无论是在代码中还是在外部,在发生此异常时强制执行与 kill -3 jvm 时获得的相同类型的线程转储?

【问题讨论】:

    标签: java oracle websphere deadlock


    【解决方案1】:

    如果您不能自动检测何时异常发生,那么知道如何枚举线程将没有多大用处。

    我们一直这样做。我们基本上是在使用:

    Thread.setDefaultUncaughtExceptionHandler
    

    当我们的应用启动,然后我们在异常发生时转储我们想要的信息:

    • Map<Thread, StackTraceElement[]> mst = Thread.getAllStackTraces();

    • Runtime.getRuntime().freeMemory()/ maxMemory() / totalMemory() 获取基本内存信息

    • 用户使用模式(如果它是用户可以与之交互的应用)

    • 自制“分析”

    然后你可以调用很多其他的东西并变得花哨。例如,我们会自动将崩溃报告(包括完整的堆栈跟踪)发送到等待此类跟踪的服务器。

    【讨论】:

    • +1;我记得当我发现这个花絮时,发生了一些小灯泡。
    • kill -3 拥有以及每个线程的堆栈跟踪信息,有关每个线程已获取并正在等待的锁的信息。 Thread.getAllStackTraces() 也有吗?
    • @Paul Tomblin:我不这么认为。我们正在使用 findDeadlockedThreads 方法来查找死锁(在支持此调用的 JVM 上)。
    【解决方案2】:

    对于当前线程,可以使用Thread.dumpStack()

    对于所有线程,您可以使用 Thread.enumerate() 获取所有正在运行的线程并使用 dumpStack() 每个线程,也可以使用 Thread.getAllStackTraces() 并将它们打印到控制台或任何您需要的地方。

    要在这些异常发生时实现这一点,如果您无法在自己的代码中执行此操作,您可以尝试 AOP,编写一个代理(如果您使用 Java 6+),或者您可以在紧要关头,获取 SQLException 的源代码,将其更改为在其构造函数中转储堆栈,重新编译并将该类放回引导类路径中。

    【讨论】:

      猜你喜欢
      • 2014-06-06
      • 2011-12-03
      • 2011-12-30
      • 1970-01-01
      • 2013-09-12
      • 2010-09-09
      • 2012-03-02
      • 2010-09-12
      • 2020-06-05
      相关资源
      最近更新 更多