Android JVM05 --- 字节码文件与类加载

117 阅读5分钟

一.前端编译器与后端编译器

前端编译器:将可读的字符串(Java,kotin)转化为汇编。

后端编译器:将汇编转化为机器码。

二.解释执行&JIT&AOT

解释执行:

程序运行过程中,逐行进行代码编译

JIT:

程序运行过程中,将热点代码进行编译缓存执行

AOT:

运行之前,将所有代码打包编译成机器码。

三.Class文件与Dex文件结构

1.魔数 4个字节,识别Class文件格式。

2.副版本号 2个字节,小版本

3.主版本号 2个字节,大版本。

4.常量池计数器 2个字节

5.常量池表 N个字节

6.访问标识 2个字节

7.类索引 2个字节

8.父类索引 2个字节

9.接口计数器 2个字节

10.接口索引集合 2个字节

11.字段计数器 2个字节

12.字段表 N个字节

13.方法计数器 2个字节

14.方法表 N个字节

15.属性计数器 2个字节

16.属性表 N个字节

四.类的生命周期

1.加载(Loading)

将一个java类的字节码文件加载到机器内存中(方法区),并在内存中构建出一个对象(该数据处于运行时数据区-方法区),该失礼了对象的模型为java.lang.Class类。

加载阶段必须完成的三件事情:

a.通过类名的全名获取类的二进制数据流。

b.解析类的二进制数据类型到方法区中。

c.创建一个java.lang.Class类的实例,标识该模型,作为方法区这个类的各种数据的访问入口。

注意:数组类的加载,由于数组本身不是由类加载器负责创建,而是由JVM在运行时根据需要直接创建,但是数组的元素类型仍需要类加载器加载。

数组类的创建过程:

a.如果数组是引用数据类型数组,那么遵循加载过程的递归在加载创建。

b.JVM使用指定元素类型和数组维度来创建新的数组类。

2.链接(Linking)

验证:保证加载的字节码是合法,合理并且符合规范的。

a.格式检查:魔术检查,版本检查,长度检查

b.语义检查:是否继承final/是否有父类/抽象方法是否有实现?

c.字节码验证:跳转指定是否指向正确位置/操作数是否合理?

d.符号引用验证:符号引用的直接引用是否存在?

准备:为类的静态变量分配内存,并将其初始化默认值。

a.这里不包含基本数据类型的字段用static,final修饰的情况,final修饰会在编译期就分配,准备阶段就赋值。

b.不会为实例变量分配初始化,类变量会分配在方法区中,而实例变量是会随着对象一起分配在堆中。

c.这个阶段不会有代码执行!!!

解析:将类,接口,字段,方法的符号引用转换为直接引用。

将符号应用转化为内存地址,比如System.out.print()对应字节码invokevirtual #24<java.io.PrintStrem.printin.....

3.初始化(Initialization)

去给相关的变量去赋予初始值。初始化最重要的工作是执行初始化方法cinit方法。

该方法有编译器产生并且调用,不能在java程序中人为调用,cinit方法包含类的静态成员与静态块的执行字节码。

注意:cinit方法不等于构造方法!!!

4.使用(Using)

主动使用的执行取决于上诉初始化阶段的cinit方法是否被调用。

a.主动使用场景:

创建一个类的实例,使用new,反射,克隆,反序列化等操作。

当使用类,接口的静态字段及静态方法时

使用反射类时。

子类初始化时,需要优先触发父类初始化

main方法所在的类

b.被动使用场景:

当访问一个静态字段时,只有正在使用这个字段的类才会被初始化

通过数组定义类引用,不会触发此类的初始化

引用常量不会触发此类或者接口的初始化,因为常量在链接阶段已经赋值。

调用ClassLoader类的loadClass方法加载一个类,并不是堆类的主动使用,不会导致类的初始化。

5.卸载(Unloading)

类,类加载器,类的实例之间的引用关联。

我们需要知道的是,一个我自己写的代码文件,如果到内存当中被使用和释放的过程

写代码---java--前端编译器--.class--通过IO读取出来--解析文件结构约定解析套路--将解析出来的数据扔到方法区--将当前这个类的信息提取出来--推动堆当中生成Class对象--具体使用--cinit--卸载

五.类加载器

读取指定目录下的相关字节码文件,解析文件。

类加载器几个关键函数:

1.loadClass:双亲委派机制

2.findClass:搜索并且提取字节码数据

3.defineClass:将字节码文件读取完后进行校验

definaClass结束,类加载结束!!!

六.热修复原理

类加载器的核心