- 我们运行一个.class文件,windows下的java.exe调用底层jvm.dll文件创建java虚拟机(c++实现)。
- 创建一个引导类加载器实例(c++实现)
- C++调用java代码Launcher,该类创建其他java类加载器。
- Launcher.getClassLoader()调用loaderClass加载运行类Math
- classLoader.loader(“com.jvm.math”)加载main方法入口
- Main运行java程序
- 类的加载
加载分为 验证、准备、解析、初始化
- 验证
.class里开头是cafe babe是字节码开头格式
如果开头不是这个,则代表不是字节码.class文件。
- 准备
类里的静态变量分配内存,先赋默认值,比如对象会先赋值为null,int会赋值为0,boolean的话会赋值为false等。加载完后才会给真实的值。
(注意:final是常量,直接赋值真实的值,加了final就是常量,不可变)
- 解析(比较复杂)
先将符号引用转成直接引用,该阶段把静态方法(比如main方法)替换为指向数据所存内存的指针,这就是所谓静态链接过程(类加载期间完成),动态链接是程序运行期间完成的将符号引用替换为直接引用。
(举个例子:main方法这一行都属于静态数据,会转换成内存里的指针,属于静态链接。而main方法里调用的其他方法,这种就属于动态链接。)
- 初始化
对类的静态初始化指定值,执行静态代码块。
最后运行 和 结束。
Jvm属于懒加载,只有依赖的时候才会去加载。
比如静态代码块,只有在加载某个类的时候执行,效果类似。
先加载类里的静态代码块,构造方法是在类加载之后调用的,因为必须类加载完构造方法初始化才可以执行,类都没加载完,构造函数必定执行不了。