首先要明白一点:JVM自己是一个多线程的程序,和咱们编写的java应用程序同样,当JVM启动执行时就是在操做系统中启动了一个JVM进程。咱们编写的java单线程或多线程应用进程都是在JVM这个程序中做为一个或多个线程运行。java
每当使用java命令执行一个带main方法的类时,就会启动JVM(应用程序),实际上就是在操做系统中启动一个JVM进程,JVM启动时,必然会建立如下5个线程:多线程
1-main 主线程,执行咱们指定的启动类的main方法jvm
2-Reference Handler 处理引用的线程 spa
3-Finalizer 调用对象的finalize方法的线程,就是垃圾回收的线程 操作系统
4-Signal Dispatcher 分发处理发送给JVM信号的线程 线程
5-Attach Listener 负责接收外部的命令的线程对象
Attach Listener :该线程是负责接收到外部的命令,执行该命令,而且把结果返回给发送者。一般咱们会用一些命令去要求jvm给咱们一些反馈信息,如:java -version、jmap、 jstack等等。若是该线程在jvm启动的时候没有初始化,那么,则会在用户第一次执行jvm命令时,获得启动。进程
signal dispather: 前面咱们提到第一个Attach Listener线程的职责是接收外部jvm命令,当命令接收成功后,会交给signal dispather线程去进行分发到各个不一样的模块处理命令,并 且返回处理结果。signal dispather线程也是在第一次接收外部jvm命令时,进行初始化工做。get
Finalizer: JVM在垃圾收集时会将失去引用的对象包装成Finalizer对象(Reference的实现),并放入ReferenceQueue,由Finalizer线程来处理;最后将该Finalizer对象的引用置为null,由垃圾收集器来回收。io
Reference Handler :它主要用于处理引用对象自己(软引用、弱引用、虚引用)的垃圾回收问题。
main:主线程,用于执行咱们编写的java程序的main方法。
可编写java应用程序查看JVM启动时建立的全部线程,代码以下:
package com.jvmTest;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
public class JVMTest {
public static void main(String[] args) throws Exception {
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
for(ThreadInfo threadInfo : threadInfos) {
System.out.println(threadInfo.getThreadId() + "-" + threadInfo.getThreadName());
}
}
}
----------------------------------------------
输出以下:
5-Attach Listener4-Signal Dispatcher3-Finalizer2-Reference Handler1-main