导图社区 JVM执行子系统
整理自周志明老师的《深入理解Java虚拟机》某一章节 内 字节码 虚拟机类加载机制 等先关介绍
编辑于2020-07-12 23:16:04虚拟机执行子系统
类文件结构
无关性的基石
Class类文件的结构
魔数与Class文件的版本
常量池
访问标志
类索引、父类索引与接口索引集合
字段表集合
方法表集合
属性表集合
Code属性
Exceptions属性
LineNumberTable属性
LocalVariableTable及LocalVariableTypeTable属性
SourceFile及SourceDebugExtension属性
ConstantValue属性
InnerClasses属性
Deprecated及Synthetic属性
StackMapTable属性
Signature属性
BootstrapMethods属性
MethodParameters属性
模块化相关属性
运行时注解相关属性
字节码指令简介
字节码与数据类型
加载和存储指令
运算指令
类型转换指令
对象创建与访问指令
操作数栈管理指令
控制转移指令
方法调用和返回指令
异常处理指令
同步指令
公有设计,私有实现
Class文件结构的发展
虚拟机类加载机制
类加载的时机
主动引用类型(6种)
字节码指令:new、getstatic、putstatic或invokestatic
java.lang.reflect
当初始化类的时候,其父类还没有进行过初始
包含main()方法的类
java.lang.invoke.MethodHandle
接口:default()
类加载的过程
加载
1)类的全限定名(二进制字节流)
2)方法区的运行时数据结构。
3)java.lang.Class对象(访问入口)
验证(安全)
文件格式验证
Class文件格式的规范
元数据验证
语义分析
字节码验证
数据流分析和控制流分析
符号引用验证
解析阶段中发生
准备
类变量(static)
分配内存并设置类变量初始值
常量(final)
ConstantValue
解析
符号引用替换为直接引用
类或接口的解析
方法解析
接口方法解析
字段解析
初始化
类构造器<clinit>()
基类
类变量的赋值动作
静态语句块(static{}块)
类加载器
类与类加载器
双亲委派模型
启动类加载器(Bootstrap Class Loader)
负责加载存放在<JAVA_HOME>\lib目录
扩展类加载器(Extension Class Loader)
负责加载<JAVA_HOME>\lib\ext目录
应用程序类加载器(Application Class Loader)
负责加载用户类路径(ClassPath)上所有的类库
自定义类加载器
工作过程
1. 把这个请求委派给父类加载器去完成
2.只有当父加载器反馈自己无法完成这个加载请求
子加载器才会尝试自己去完成加载。
破坏双亲委派模型
Java模块化系统
模块的兼容性
模块化下的类加载器
虚拟机字节码执行引擎
运行时栈帧结构
局部变量表
变量槽(Variable Slot)
局部变量定义了但没有赋初始值,不能使用
操作数栈
操作数栈中元素的数据类型必须与字节码指令的序列严格匹配
静态解析
动态连接
每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用
方法返回地址
Normal Method Invocation Completion
Abrupt Method InvocationCompletion
附加信息
与调试、性能收集相关
方法调用
唯一目的:确定被调方法的版本
解析
非虚方法”(Non-Virtual Method)
确定唯一的调用版本
invokespecial
私有方法
实例构造器
父类方法
invokestatic
静态方法
final
虚方法”(VirtualMethod)
分派(方法版本)
静态分派(编译阶段)
依赖静态类型(重载)
动态分派(多态)
invokevirtual的执行逻辑
只对方法有效,对字段无效
重写
单分派与多分派
虚拟机动态分派的实现
动态类型语言支持
动态类型语言
Java与动态类型
java.lang.invoke包
invokedynamic指令
实战:掌控方法分派规则
基于栈的字节码解释执行引擎
解释执行
基于栈的指令集与基于寄存器的指令集
基于栈的解释器执行过程