首页 > 解决方案 > visualvm 采样器的“CPU 样本”选项卡和“线程 CPU 时间”选项卡有什么区别?

问题描述

当我使用 visualvm 时,我对采样器的“CPU 样本”选项卡和“线程 CPU 时间”选项卡感到困惑。以下屏幕截图分别在这两个选项卡中显示了相同的线程“Monitor Ctrl-Break”:

“CPU 样本”选项卡中的 CPU 时间为 1082903 毫秒。

“线程 CPU 时间”选项卡中的 CPU 时间仅为 15.6 毫秒!

我的问题:

  1. 为什么这两个选项卡中的 CPU 时间差异如此之大?

  2. 这两个CPU时间是什么意思?换句话说,这两个 CPU 时间由哪些部分组成?

期待一些答复。谢谢你们。

标签: javaperformanceoptimizationoperating-systemvisualvm

解决方案


不同之处在于 JVM 不知道本地方法是否阻塞。

考虑一个简单的例子:

public class Test {
    public static void main(String[] args) throws Exception {
        System.in.read();
    }
}

如果标准输入是控制台,并且用户没有输入任何内容,则该方法InputStream.read将阻塞。如果标准输入是磁盘上的文件,read将立即返回文件的第一个字节。JVM 不区分这两种情况;它发生在操作系统级别。从 JVM 的角度来看,线程执行FileInputStream.read方法始终处于RUNNABLE状态,即使底层 I/O 可能在操作系统级别阻塞。

VisualVM 中的 CPU 采样器将RUNNABLE线程视为消耗 CPU。
相反,Thread CPU time选项卡直接从操作系统获取统计信息,从而显示真实的 CPU 使用率。

read因此,如果一个线程在一个本地方法(如 事实上,这种方法并没有消耗 CPU 时间,但是 VisualVM 看到一个线程是RUNNABLE繁忙的。

VisualVM 并不是唯一遇到此问题的分析器。这实际上是所有基于标准 Java API 获取线程堆栈跟踪的采样分析器的常见谬误。在我的演示文稿中找到更多详细信息。


推荐阅读