JVM解释器和编译器

内容概要: 浅析JVM解释器和编译器

1. 浅析JVM解释器Interpreter和编译器Compiler

以HotSpot虚拟机为例, 它采用的是interpreter和Compiler并存的架构.
HotSpot内置了interpreter和两个compiler, c1(client) compiler和c2(server) compiler.
1.1 JVM的执行模式
默认为mixed mode:

1
2
3
4
java -version
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)

指定以interpreter运行某个程序:

1
2
java -Xint org.HelloWorld 
Hello World!

打印这时候虚拟机启动的线程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
jstack 15952
2017-10-13 11:26:47
Full thread dump Java HotSpot(TM) 64-Bit Server VM ("25.112-b15 interpreted mode"):

"Attach Listener" #6 daemon prio=9 os_prio=0 tid=0x00007eff14001000 nid=0x3e7b waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Service Thread" #5 daemon prio=9 os_prio=0 tid=0x00007eff500b8800 nid=0x3e5a runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007eff500b7000 nid=0x3e59 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007eff50083800 nid=0x3e58 in Object.wait() [0x00007eff33efd000]
java.lang.Thread.State: WAITING (on object monitor)

"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007eff5007f000 nid=0x3e57 in Object.wait() [0x00007eff33ffe000]
java.lang.Thread.State: WAITING (on object monitor)

"main" #1 prio=5 os_prio=0 tid=0x00007eff50009800 nid=0x3e51 runnable [0x00007eff58ccd000]
java.lang.Thread.State: RUNNABLE

"VM Thread" os_prio=0 tid=0x00007eff50077800 nid=0x3e56 runnable

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007eff5001f000 nid=0x3e52 runnable

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007eff50020800 nid=0x3e53 runnable

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007eff50022800 nid=0x3e54 runnable

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007eff50024000 nid=0x3e55 runnable

"VM Periodic Task Thread" os_prio=0 tid=0x00007eff500bc000 nid=0x3e5b waiting on condition

JNI global references: 6

指定以compiler运行某个程序, 可以看到启动速度明显慢了很多, 即便只是一个很简单的程序:

1
2
java -Xcomp org.HelloWorld
Hello World!

可以看到, 这时候多了三个compiler线程, 其中C1为client compiler, c2为server compiler:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
jstack 12952
2017-10-13 11:13:09
Full thread dump Java HotSpot(TM) 64-Bit Server VM ("25.112-b15 compiled mode"):

"Attach Listener" #9 daemon prio=9 os_prio=0 tid=0x00007f4158001000 nid=0x32c7 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Service Thread" #8 daemon prio=9 os_prio=0 tid=0x00007f41940c3000 nid=0x32a5 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"C1 CompilerThread2" #7 daemon prio=9 os_prio=0 tid=0x00007f41940bd000 nid=0x32a4 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f41940bb000 nid=0x32a3 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f41940b8000 nid=0x32a2 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

...

JNI global references: 11

1.2 JVM系统线程

线程类别 Thread 功能
虚拟机线程 VM Thread 这个线程等待 JVM 到达安全点操作出现。这些操作必须要在独立的线程里执行,因为当堆修改无法进行时,线程都需要 JVM 位于安全点。这些操作的类型有:stop-the-world 垃圾回收、线程栈 dump、线程暂停、线程偏向锁(biased locking)解除
周期性任务线程 VM Periodic Task Thread 这线程负责定时器事件(也就是中断),用来调度周期性操作的执行。
GC线程 GC task thread 这些线程支持 JVM 中不同的垃圾回收活动。
信号分发线程 Signal Dispatcher 这个线程接收发送到 JVM 的信号并调用适当的 JVM 方法处理。
编译器线程 C1/C2 CompilerThread 这些线程在运行时将字节码动态编译成本地平台相关的机器码。