如何在Java虚拟线程中测量CPU时间?

3
在Java中,要测量线程使用的CPU时间,通常会做类似这样的操作:
var cpuTimeStart = ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();
//Some lengthy operation
var totalCPU = ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime() - cpuTimeStart;

这个方法在之前运行得很好。但是自从引入了虚拟线程(JDK 21)之后,这个方法只适用于平台线程,而不适用于虚拟线程。
所以现在它总是报告为0:
var vThread = Thread.ofVirtual().start(() -> {
  var cpuTimeStart = ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();
  //Some lengthy operation
  var totalCPU = ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime() - cpuTimeStart;
  //totalCPU is always 0
});
vThread.join();

那么,问题是在引入虚拟线程后,我们应该如何测量CPU时间呢?
1个回答

1
所以,问题是在引入虚拟线程后,我们应该如何测量CPU时间?
我认为这是不可能的。
为什么呢?因为要测量虚拟线程的CPU时间,运行时需要进行系统调用来查找和记录当前(非虚拟)线程的CPU时间...每次进行虚拟线程切换时都需要进行。这些系统调用的开销将大大削弱实现虚拟线程的初衷。

我明白对于非常短的操作来说,这可能是可取的,但现实世界是...更加复杂。考虑一下在Tomcat中的VirtualThreadExecutor,如果有人启用它,将无法对其进行分析。我想知道性能分析工具如何可能解决这个问题(例如:https://github.com/newrelic/newrelic-java-agent/blob/6e6c4db548243b5c438f27ba9dffaf511ae204db/newrelic-agent/src/main/java/com/newrelic/agent/profile/v2/Profile.java#LL90C1-L90C1) - cocorossello
我觉得你没有理解我的意思。如果虚拟线程能够支持CPU测量,那么对于大多数不需要CPU测量的用例来说,它们将变得过慢。如果你需要能够测量线程的CPU时间,就不应该使用虚拟线程。 - Stephen C
我觉得你没有理解我的观点。如果虚拟线程确实支持CPU测量,那么对于大多数不需要CPU测量的用例来说,它们将变得太慢了。如果你需要能够测量线程的CPU时间,就不应该使用虚拟线程。 - Stephen C
也许你应该问那个性能分析工具的作者,他们打算如何解决这个(在我看来)无法解决的问题 :-) - Stephen C
也许你应该问一下那个分析工具的作者,看他们打算如何解决这个(在我看来)无法解决的问题 :-) - Stephen C
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接