首先要明白一點:JVM本身是一個多線程的程序,和我們編寫的java應用程序一樣,當JVM啟動執行時就是在操作系統中啟動了一個JVM進程。我們編寫的java單線程或多線程應用進程都是在JVM這個程序中作為一個或多個線程運行。
每當使用java命令執行一個帶main方法的類時,就會啟動JVM(應用程序),實際上就是在操作系統中啟動一個JVM進程,JVM啟動時,必然會創建以下5個線程:
1-main 主線程,執行我們指定的啟動類的main方法
2-Reference Handler 處理引用的線程
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命令時,進行初始化工作。
Finalizer: JVM在垃圾收集時會將失去引用的對象包裝成Finalizer對象(Reference的實現),並放入ReferenceQueue,由Finalizer線程來處理;最后將該Finalizer對象的引用置為null,由垃圾收集器來回收。
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 Listener
4-Signal Dispatcher
3-Finalizer
2-Reference Handler
1-main