使用JMX获取线程CPU时间的有效方法

时间:2009-06-09 16:03:47

标签: java jmx

我目前正在以下列方式使用JMX获取总线程CPU时间:

private long calculateTotalThreadCpuTime(ThreadMXBean thread) {

    long totalTime = 0l;

    for (ThreadInfo threadInfo : thread.dumpAllThreads(false, false))
        totalTime += thread.getThreadCpuTime(threadInfo.getThreadId());

    return totalTime;
}

由于ThreadMXBean实际上是一个远程代理,因此该实际方法调用的性能为 dreadful ,大小为秒。

有更快的方法吗?


更新:我正在使用它进行性能监控。测量结果是“挂钟”时间和JProfiler,显示我花费大约85%的时间用于此方法。我确实有一些其他MXBean调用(运行时,内存,GC),但它们便宜得多。很可能是因为对thread.getThreadCpuTime的每次呼叫都是远程呼叫。

更新2 :显示性能问题的JProfiler屏幕截图。

alt text

5 个答案:

答案 0 :(得分:3)

如果您愿意使用非标准API,可以将OperatingSystemMXBean投射到com.sun.management.OperatingSystemMXBean并调用getProcessCpuTime(),如David Robert Nadeau博客上的Using a Sun internal class to get JVM CPU time所述。

答案 1 :(得分:2)

问题必须是你的电话的远程性质。

我最近在询问线程的CPU时间使用时出现了高峰,而且速度非常快。在Web应用程序请求的上下文中,它几乎是无法估量的。如果一个人进入硬循环会花费你,但通常你想在操作开始时和最后一次。

答案 2 :(得分:1)

的优化:

  • 在线程池中调用getThreadCPUTime,因为它似乎是网络绑定的;
  • 每当发现某个帖子位于Thread.STATE.TERMINATED时,请将其名称保存在地图中,并在下次跳过查询。

答案 3 :(得分:1)

性能不佳的原因是thread.getThreadCpuTime()的每次调用(在你的远程代理的情况下)最有可能导致RMI / Remote JMX调用,这当然是昂贵的,特别是当消息是实际上通过TCP发送(甚至可能在localhost之外)。 (see JMX 1.4 spec, chapter 7.3)

虽然JMX一次定义multiple attribute retrieval,但这对你没有帮助 因为thread.getThreadCpuTime(long)不是JMX属性而是远程方法调用(此外,调用方法的ThreadInfo对象因每次调用而不同)

不幸的是,JMX 1.4规范没有定义类似“调用多个对象的多个方法并返回它们的返回值”。 因此,除了这些调用的并发调用(这将节省时间但不会减少工作量)之外,我不知道这里有任何(兼容的)优化。

答案 4 :(得分:0)

您能详细谈谈您计划如何使用这些信息吗?您可以使用基于JVMTI的代理获取线程CPU时间,该代理的性能应该略好于JMX。您是如何衡量JMX方法的开销,导致您获得“可怕”的表现?