有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java visualvm采样器的“CPU样本”选项卡和“线程CPU时间”选项卡之间有什么区别?

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

CPU time in "CPU samples" tab为1082903ms

CPU time in "Thread CPU Time" tab只有15.6ms

我的问题是:

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

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

期待一些答复。谢谢大家


共 (1) 个答案

  1. # 1 楼答案

    区别在于JVM不知道本机方法是否阻塞

    考虑一个简单的例子:

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

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

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

    因此,如果线程阻塞在像read这样的本机方法中,则从JVM的角度来看它是可运行的,但从OS的角度来看它是空闲的。事实上,这种方法不会占用CPU时间,但VisualVM会看到线程处于RUNNABLE状态,并将其计为繁忙状态

    VisualVM并不是唯一遇到此问题的探查器。这实际上是所有基于标准JavaAPI的采样分析器获取线程堆栈跟踪的常见错误。在my presentation中找到更多详细信息