java虚拟机连接模型

动态连接和解析:
java二进制文件只保存了一个类型对另一个类型的符号引用,符号引用在解析后被替换为直接引用,只有当虚拟机首次使用符号引用时才会把符号引用替换为直接引用,如果引用有错,在首次使用时抛出错误。

动态扩展:
两种动态扩展方式:1.使用java.lang.Class的forName()方法,2.使用java.lang.ClassLoader创建子类用户自定义装载器,再使用类装载器的loadClass()方法

类装载器和双亲委派模型:
每一个用户自定义的类装载器在创建时被分配一个双亲类装载器,如果没有显示指定,系统默认类装载器为双亲。如果在调用用户自定义的新装载器的时候,双亲装载器显示传递过去,则此为其双亲装载器。如果传递给构造方法的是一个用户自定义的装载器,该装载器为双亲,如果构造方法传递为null,启动装载器为其双亲

常量池解析:
CONSTANT_Class_info入口解析:
1.数组类:
若CONSTANT_Class_info入口的name_index指向CONSTANT_Utf8_info字符串由左边方括号开始,则其指向一个数组类,指向数组类的符号引用最终解析结果是一个Class实例,表示该数组类,如果当前类装载器已经被记录为解析的数组类的初始装载器,则使用同样的类。
2.非数组类和接口:
若CONSTANT_Class_info入口的name_index指向CONSTANT_Utf8_info不是由左方括号开始,则其指向非数组类或者接口的符号引用,解析这种类型步骤如下:
步骤1:装载器类型或者任何超类型
步骤2:检查访问权限
步骤3:连接并初始化类型和任何超类
步骤4:校验类型
步骤5:解析类型
步骤6:初始化类型

CONSTANT_Fieldref_infor入口解析:
步骤如下:
步骤1:虚拟机查找引用类型的具体名字和字段,若找到,则此字段成功
步骤2:虚拟机检查类型直接实现或扩展的接口或者超接口,如果找到,则此字段成功
步骤3:如果类型拥有一个直接的超类,虚拟机检查类型的直接超类或者所有超类,如果找到,则此字段成功
步骤4:如果以上未找到,则字段搜索失败

CONSTANT_Methodref_info入口解析:
步骤如下:
步骤1:如果解析类型是一个借口,虚拟机抛出异常
步骤2:如果解析类型是一个类,检查引用类是否含有一个方法符合指定名字以及描述符,如果找到,搜索成功
步骤3:如果类有一个直接超类,虚拟机检查直接超类和所有超类是否含有符合的方法名字和描述符,如果找到,则搜索成功
步骤4:检查这个类是否直接实现了任何借口,并检查所有超接口,找到,则返回搜索结果
步骤5:搜索失败,抛出NoSuchMethodError异常

装载约束:
为了确保java虚拟机实现能够保证类型在不同命名空间的一致性,java虚拟机规范了几种装载约束。

编译时常量解析:
被初始化为编译常量的静态final引用,在编译时解析为常量值的一个本地拷贝,对于所有基本类型和java.lang.String都是正确的。其有两个特性:1.常量值得本地拷贝使得其可以用于switch语句中的case表达式,2.其不支持运行时解析case值,

直接引用:
指向类型、类变量和类方法的直接引用可能是指向方法区的本地指针。指向实例变量和实例方法的直接引用都是偏移量,

_quick指令:
作用:加速字节码解释

猜你喜欢

转载自blog.csdn.net/weixin_43638314/article/details/91558683