【问题标题】:How do I figure out what's holding a lock and blocking my Java thread?如何确定是什么持有锁并阻塞了我的 Java 线程?
【发布时间】:2018-09-10 20:09:10
【问题描述】:

我在 Amazon Linux 上使用 Wildfly 11 和 Java 8。我们正在解决 CPU 使用率过高的问题,我们可以使用 Wildfly CLI 工具。我注意到我们的一些 Java 线程已经运行了很长一段时间,并且想找出原因。我找到了一个线程的ID并检查了它的状态......

[standalone@localhost:9990 /] /core-service=platform-mbean/type=threading/:get-thread-infos (ids=[2L])
{
    "outcome" => "success",
    "result" => [{
        "thread-id" => 2L,
        "thread-name" => "Reference Handler",
        "thread-state" => "WAITING",
        "blocked-time" => -1L,
        "blocked-count" => 48628L,
        "waited-time" => -1L,
        "waited-count" => 44877L,
        "lock-info" => {
            "class-name" => "java.lang.ref.Reference$Lock",
            "identity-hash-code" => 926576350
        },
        "lock-name" => "java.lang.ref.Reference$Lock@373a6ede",
        "lock-owner-id" => -1L,
        "lock-owner-name" => undefined,
        "stack-trace" => [],
        "suspended" => false,
        "in-native" => false,
        "locked-monitors" => [],
        "locked-synchronizers" => []
    }]
}

我对这里的所有内容都没有深入的了解,但似乎一个问题是锁—— "class-name" => "java.lang.ref.Reference$Lock" 。有谁知道我如何获得有关导致锁定的原因的更多信息?

【问题讨论】:

  • 您还可以通过在命令行输入kill -QUIT <processid> 来获取线程转储。 FWIW,锁通常不会导致高 CPU。
  • 您是否可以更改 JVM 参数?我是的,您可以启用远程 JMX 访问并远程触发线程和堆转储。

标签: java multithreading locking wildfly cpu-usage


【解决方案1】:

你可以使用 ssh 进入盒子吗?

如果您使用 JDK(不是 JRE)运行 Java 进程,您可以使用 jstack 实用程序检查线程的状态。

如果是,您可以使用以下方法立即获取进程所有线程的线程转储:

jstack <process_id>

您可以使用

保存到文件中
jstack <process_id> > <file_name>

然后您可以在file_name 中检查线程和线程锁的状态。您可能会弄清楚哪些线程被阻塞以及它们持有哪些锁。

jstack 命令不会停止进程。在正在运行的进程上运行它是安全的。

对于任何被阻塞的 Java 应用程序,至少我将从这个简单的方法开始。

【讨论】:

  • 虽然我可以使用 SSH 进入盒子,但盒子上没有 jstack。我们只有 JRE 和 Wildfly CLI 工具可供我们使用(以及默认的 Amazon Linux 工具)。
  • 哦,对不起:(
猜你喜欢
  • 2013-09-08
  • 2011-04-15
  • 2013-04-02
  • 2016-01-11
  • 2011-10-27
  • 2020-01-02
  • 2021-07-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多