Linux top命令如何确定Java进程的状态?

[更新:在top ,按Shift + H,它显示线程,而不是进程,然后显示Java线程为R,并使用100%的CPU时间,这是我希望发布此问题之前。

由于Java进程有多个线程,每个线程可能处于不同的状态,那么Linux top命令如何确定Java进程状态?

如果我运行下面的代码,

 public class Test{ public static void main(String[] args){ while (true){ int n = (int)(Math.random() * 1000); } } } 

然后,运行top显示进程状态是S,它使用100%的CPU时间。

此外,运行strace显示,只显示:

futex(0x7f6ba759c9d0, FUTEX_WAIT, 26060, NULL

但是,运行jstack显示主线程是RUNNABLE:

 "main" prio=10 tid=0x00007fd7ec007800 nid=0x669b runnable [0x00007fd7f5754000] java.lang.Thread.State: RUNNABLE at Test.main(Test.java:5) 

jstack还显示,WAITING状态下只有两个线程:

 "Finalizer" daemon prio=10 tid=0x00007fd7ec080000 nid=0x66a6 in Object.wait() [0x00007fd7f0252000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000007ad001310> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:133) - locked <0x00000007ad001310> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:149) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177) "Reference Handler" daemon prio=10 tid=0x00007fd7ec07e000 nid=0x66a5 in Object.wait() [0x00007fd7f0353000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000007ad0011e8> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133) - locked <0x00000007ad0011e8> (a java.lang.ref.Reference$Lock) 

一个JVM有很多线程在运行,像垃圾回收等那样“管家”,大部分时间处于睡眠状态。

然后,运行顶部显示进程状态是S,它使用100%的CPU时间。

我认为这个问题很有可能与最top决定进程状态的方式有关。 在操作系统级别,单个线程具有运行/等待/休眠状态。 我的猜测是, top命令的启发式算法是为这个过程计算一个名义上的运行/等待/睡眠状态是一种误导。

(和jstack的输出…和常识…支持这个理论。)

这个线程忙于使用一个CPU,它不睡觉。

 "main" prio=10 tid=0x00007fd7ec007800 nid=0x669b runnable [0x00007fd7f5754000] java.lang.Thread.State: RUNNABLE at Test.main(Test.java:5) 

这表明顶部的信息是不正确的。

有很多关于“为什么你有多个线程,以及他们在Java中做什么”的解释,但是没有太多的解释。 top命令本身非常简单,只需要通过系统调用收集信息,例如使用getrusage来获取CPU使用率。

通常,正如所解释的, top看起来是整个过程,所有的线程一次。 你可以在top按“H”,它将显示单个线程,而不是整个过程,然后你将能够看到所有的Java线程[如果你的屏幕足够高],主要的是使用所有的CPU你的无限循环,其他线程主要是无所事事。