我写了一个Java程序,它会休眠一段时间:
package com.mycompany.app; import java.lang.System; import java.util.concurrent.TimeUnit; public class Main { public static void main(String[] args) { System.out.println("the current process's pid is " + ProcessHandle.current().pid()); try { TimeUnit.SECONDS.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Hello World!"); // Prints the string to the console. } }
我使用以下程序运行该程序:
$ java -cp target com.mycompany.app.Main the current process's pid is 10172
我检查了Ubuntu创建的运行它的过程:
$ pstree -pau -l -G -s 10172 systemd,1 splash └─lxterminal,3194,t └─bash,12150 └─java,10172 -cp target com.mycompany.app.Main ├─{java},10173 ├─{java},10174 ├─{java},10175 ├─{java},10176 ├─{java},10177 ├─{java},10178 ├─{java},10179 ├─{java},10180 ├─{java},10181 ├─{java},10182 ├─{java},10183 ├─{java},10184 ├─{java},10185 ├─{java},10186 ├─{java},10187 ├─{java},10188 ├─{java},10189 └─{java},10190
所有这些线程都属于JVM。 运行jstack <pid>以获取线程列表。
jstack <pid>
"main" #1 prio=5 os_prio=0 cpu=150.00ms elapsed=8.04s tid=0x00007f9f90011000 nid=0x107 waiting on condition [0x00007f9f99f9f000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(java.base@11.0.1/Native Method) at java.lang.Thread.sleep(java.base@11.0.1/Thread.java:339) at java.util.concurrent.TimeUnit.sleep(java.base@11.0.1/TimeUnit.java:446) at com.mycompany.app.Main.main(Main.java:10) "Reference Handler" #2 daemon prio=10 os_prio=0 cpu=0.00ms elapsed=7.95s tid=0x00007f9f901f9000 nid=0x10e waiting on condition [0x00007f9f6c10f000] java.lang.Thread.State: RUNNABLE at java.lang.ref.Reference.waitForReferencePendingList(java.base@11.0.1/Native Method) at java.lang.ref.Reference.processPendingReferences(java.base@11.0.1/Reference.java:241) at java.lang.ref.Reference$ReferenceHandler.run(java.base@11.0.1/Reference.java:213) "Finalizer" #3 daemon prio=8 os_prio=0 cpu=0.00ms elapsed=7.95s tid=0x00007f9f901fd800 nid=0x10f in Object.wait() [0x00007f9f65fef000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(java.base@11.0.1/Native Method) - waiting on <0x0000000712108f80> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(java.base@11.0.1/ReferenceQueue.java:155) - waiting to re-lock in wait() <0x0000000712108f80> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(java.base@11.0.1/ReferenceQueue.java:176) at java.lang.ref.Finalizer$FinalizerThread.run(java.base@11.0.1/Finalizer.java:170) "Signal Dispatcher" #4 daemon prio=9 os_prio=0 cpu=0.00ms elapsed=7.93s tid=0x00007f9f90210000 nid=0x110 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread0" #5 daemon prio=9 os_prio=0 cpu=40.00ms elapsed=7.93s tid=0x00007f9f90212000 nid=0x111 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE No compile task "C1 CompilerThread0" #7 daemon prio=9 os_prio=0 cpu=40.00ms elapsed=7.93s tid=0x00007f9f90214000 nid=0x112 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE No compile task "Sweeper thread" #8 daemon prio=9 os_prio=0 cpu=10.00ms elapsed=7.93s tid=0x00007f9f90216000 nid=0x113 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Service Thread" #9 daemon prio=9 os_prio=0 cpu=0.00ms elapsed=7.90s tid=0x00007f9f902d3800 nid=0x114 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Common-Cleaner" #10 daemon prio=8 os_prio=0 cpu=0.00ms elapsed=7.89s tid=0x00007f9f902df800 nid=0x116 in Object.wait() [0x00007f9f656ef000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(java.base@11.0.1/Native Method) - waiting on <0x0000000712002df0> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(java.base@11.0.1/ReferenceQueue.java:155) - waiting to re-lock in wait() <0x0000000712002df0> (a java.lang.ref.ReferenceQueue$Lock) at jdk.internal.ref.CleanerImpl.run(java.base@11.0.1/CleanerImpl.java:148) at java.lang.Thread.run(java.base@11.0.1/Thread.java:834) at jdk.internal.misc.InnocuousThread.run(java.base@11.0.1/InnocuousThread.java:134) "Attach Listener" #11 daemon prio=9 os_prio=0 cpu=0.00ms elapsed=0.21s tid=0x00007f9f44001000 nid=0x126 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "VM Thread" os_prio=0 cpu=0.00ms elapsed=7.95s tid=0x00007f9f901f1000 nid=0x10d runnable "GC Thread#0" os_prio=0 cpu=0.00ms elapsed=8.01s tid=0x00007f9f90038800 nid=0x108 runnable "G1 Main Marker" os_prio=0 cpu=0.00ms elapsed=8.00s tid=0x00007f9f90097800 nid=0x109 runnable "G1 Conc#0" os_prio=0 cpu=0.00ms elapsed=8.00s tid=0x00007f9f90099800 nid=0x10a runnable "G1 Refine#0" os_prio=0 cpu=0.00ms elapsed=8.00s tid=0x00007f9f9018d000 nid=0x10b runnable "G1 Young RemSet Sampling" os_prio=0 cpu=0.00ms elapsed=8.00s tid=0x00007f9f9018f000 nid=0x10c runnable "VM Periodic Task Thread" os_prio=0 cpu=0.00ms elapsed=7.90s tid=0x00007f9f902d6000 nid=0x115 waiting on condition
这nid是操作系统中线程的十六进制ID,您可以将其与的输出匹配pstree。
第一个命名main的线程是执行代码的线程。
Reference Handler线程负责将垃圾收集器发现的弱引用,软引用和幻像引用添加到其注册的ReferenceQueues中。
Reference Handler
Finalizerfinalize准备运行的对象的线程运行方法。
Finalizerfinalize
Signal Dispatcher等待特定的操作系统信号并处理它们。特别是,它使线程转储上SIGQUIT,还启动对VM关机过程SIGTERM,SIGINT和SIGHUP。
Signal Dispatcher
CompilerThreads 执行字节码的JIT编译。
CompilerThreads
Sweeper thread 清理过时的编译方法。
Sweeper thread
Service Thread 运行一些后台JVM任务:检测内存不足情况,清理StringTable和SymbolTable,发送延迟的JVMTI事件和GC通知等。
Service Thread
Common-Cleaner运行java.lang.ref.Cleaner实例的清理操作。
Common-Cleaner
Attach Listener线程支持动态附加机制。它侦听传入的动态附加连接并执行VM命令。例如,它是由使用jstack,jmap与jcmd实用程序。
Attach Listener
VM Thread运行需要一个内部VM操作还原点。这样的操作的示例是反优化,类重新定义,有偏的锁吊销,线程转储,堆检查等。
VM Thread
G1 线程参与垃圾回收。
G1
VM Periodic Task Thread 用于模拟定时器中断。
VM Periodic Task Thread