1. 启动入口

sun.misc.Launcher类是java的入口,在启动java应用的时候会首先创建Launcher类,创建Launcher类的时候会准备应用程序运行中需要的类加载器,位于jre/lib/rt.jar中。

Launcher作为JAVA应用的入口,根据双亲委派模型,Laucher是由JVM创建的,它的类加载器是BootStrapClassLoader, 这是一个C++编写的类加载器,是java应用体系中最顶层的类加载器,负责加载JVM需要的一些类库(/lib),而Launcher类在rt.jar中,正好处于该加载器的加载路径下。

2. 启动流程

3. ClassLoader初始化源码解读

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//JDK 1.8 

public class Launcher {
private static Launcher launcher = new Launcher(); //类被加载时,触发创建静态实例对象,进而触发构造函数

public Launcher() { //构造函数
ExtClassLoader extClassLoader;
try {
extClassLoader = ExtClassLoader.getExtClassLoader(); // 获取ExtClassLoader
} catch (IOException iOException) {
throw new InternalError("Could not create extension class loader");
}
try {
this.loader = AppClassLoader.getAppClassLoader(extClassLoader); //以ExtClassLoader 作为父类加载器创建一个AppClassLoader
} catch (IOException iOException) {
throw new InternalError("Could not create application class loader");
}
Thread.currentThread().setContextClassLoader(this.loader); //设置默认加载器
....
}
}

首先我们知道Launcher类是应用的入口,位于rt.jar包中,默认会被BootstrapClassLoader加载,被加载时,触发创建静态实例对象,进而触发构造函数,在构造函数内,完成ExtClassLoader及AppClassLoader的创建并设置线程上下文类加载器。

3.1. ExtClassLoader

Launcher在创建的时候,第一件事情就是获取ExtClassLoader, ExtClassLoader在JVM中是一个单例, 创建过程也是通过获取环境变量来获取ext加载的目录,生成一个ExtClassLoader,ExtClassLoader是URLClassLoader的子类。

1
2
3
4
5
6
7
8
9
10
11
public static Launcher.ExtClassLoader getExtClassLoader() throws IOException {
if (instance == null) {
Class clazz = Launcher.ExtClassLoader.class;
synchronized(Launcher.ExtClassLoader.class) {
if (instance == null) {
instance = createExtClassLoader(); //单例模式
}
}
}
return instance;
}


ExtClassLoader的parent在此处设置为了null

3.2. AppClassLoader

在获取ExtClassLoader之后,以此作为父类加载器创建一个sun.misc.Launcher.AppClassLoader, AppClassLoader的加载路径是java.class.path标记的路径,相同的,AppClassLoader也是URLClassLoader的子类。

3.3. ContextClassLoader

第18行,最终会将当前线程的上下文类加载器设置为AppClassLoader

4. JVM启动流程

4.1. 总体流程

虚拟机的启动入口位于 share/tools/launcher/java.c 的 main 方法,整个流程分为如下几个步骤:
1、配置JVM装载环境
2、解析JVM参数
3、设置线程栈大小
4、执行Java main方法: [[JVM源码分析之JVM启动流程_猿灯塔_InfoQ写作社区#2、加载主类的 class]]

[[JVM源码分析之JVM启动流程_猿灯塔_InfoQ写作社区]]

4.2. 创建引导类加载器流程

#todo

- [ ] 🚩 - 学习创建引导类加载器详细流程 - 🏡 2023-01-24 14:48 https://blog.csdn.net/luanlouis/article/details/50529868

5. 参考与感谢

https://blog.csdn.net/m0_45406092/article/details/108984101
https://cloud.tencent.com/developer/article/2132669

JDK9类加载器变化:[[探秘Java9之类加载 - 掘金]]

[[HotSpot JVM 的启动过程做了什么? - 知乎]]

https://xie.infoq.cn/article/509ebe9333a72b65b2fe85534

https://cloud.tencent.com/developer/article/1038435