我目前正在以下列方式使用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屏幕截图。
答案 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)
的优化:
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方法的开销,导致您获得“可怕”的表现?