【问题标题】:Finding waiting objects寻找等待对象
【发布时间】:2012-09-02 13:22:00
【问题描述】:

我们使用 jvisualvm 分析了我们的应用程序,发现它在 Object.wait() 中花费了很多时间。

如何找到调用此方法的对象?

【问题讨论】:

  • wait是对象的静态成员吗​​?
  • Wait 是继承自 Object 的方法。它通常在并发对象尝试访问监视器时调用(即具有同步方法的类)。 JVM 通过调用 wait() 将第二个调用者置于等待状态。由于它不知道调用者的类型,它只能执行 Object.wait()
  • 欢迎使用分析。 Here's what actually workshere's why。更多 reasons why.
  • 这些链接很有趣,但对于许多应用程序应用程序来说,所描述的技术将是多余的。其次,Sun(现在的 Oracle)在 VisualVM 和 JConsole 上投入了大量精力,因此不使用它们是愚蠢的(以具有相同经验的人盯着 SIGKILL 生成的线程转储编写)。
  • @noahz:只要付出足够的努力就能让某件事变得有价值。真正归结为您对速度的需求有多严重,因为 SO 充满了问题和对此效果的评论:我的分析器令人困惑,但似乎没有向我显示任何瓶颈,所以我想我会假设没有。

标签: java debugging concurrency profiling


【解决方案1】:

事实上,Java SE SDK 带有一个有用的类ThreadInfo,您可以检查它以了解线程被阻塞的原因以及它正在等待什么,包括到等待点的完整堆栈跟踪,以及在毫秒等待。

您可以通过java.lang.management 包特别是ManagementFactory.getThreadMXBean() 使用此类,然后您可以使用此类以编程方式检查您的阻塞线程。

这是来自 JConsole 的相关截图:

【讨论】:

  • 对不起,我是 JMX 的菜鸟。我可以从 viusalvm 访问它还是需要编写额外的监控代码?
  • 两者。 VisualVM 使用 API 来监控 JVM,您可以使用 API 编写自己的自定义监控/分析组件。
【解决方案2】:

如果您不限于 jvisualvm,则可以在 JProfiler 中右键单击锁定图中的对象并在堆遍历器中检查它。

这是针对当前锁定情况的,但历史视图可以让您访问以前的锁定情况,并且还有一个监视器统计视图,可以按其类细分监视器:

免责声明:我公司开发 JProfiler。

【讨论】:

    【解决方案3】:

    挂在Object.wait() 上是完全合法且安全的情况,例如,当某个线程正在等待BlockingQueue 中的新元素时,可能会发生这种情况。这种等待所花费的时间不应影响应用程序的性能,除非它是死锁。

    【讨论】:

    • 我并不是说这很糟糕。我只是对我的哪些活动对象正在等待感兴趣。仅看到系统在 Object.wait() 中花费了一半的周期,我无法学到很多东西。所以问题是“谁”在等待,为什么;-)
    • 等待时间绝对会影响应用程序的性能。
    猜你喜欢
    • 2020-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-03
    • 1970-01-01
    • 2016-01-17
    • 2020-09-12
    • 2016-10-09
    相关资源
    最近更新 更多