JVM浅析总结(执行引擎)
# 执行引擎(Execution Engine)
执行引擎(Execution Engine)的作用:将字节码指令解释/编译为对应平台的本地机器指令,简而言之,将高级语言转译成机器语言能被计算机识别
执行引擎的简单工作工程
- 通过pc寄存器确定一条执行指令
- 执行完一条指令后,pc寄存器指向下一条指令地址
- 执行构成中可以通过存储在虚拟机栈中局部变量表(Local Variables)的对象引用定位到java堆中的对象实例信息.通过对象头中的元数据指针定位到目标对象的类型信息
# JAVA后端编译和执行的过程
名词解释 | 说明 |
---|---|
解释器(Interpreter) | java虚拟机对字节码采用逐行解释的方式执行,将字节码翻译为本地机器指令执行 |
JIT编译器(just in time) | 虚拟机将源代码直接编译成本地机器指令执行 |
机器码 | 二进制编码方式表示的指令 |
指令 | 把机器码中特定的0和1序列简化成对应的指令 |
指令集 | 每个平台持有的指令集 |
汇编语言 | 用助记符代替机器指令的操作码,用地址符号或标号代替指令或操作数的地址 |
- 当程序需要迅速启动然后执行的时候,解释器可以首先发挥作用,编译器不运行从而省去编译时间,立即执行程序
- 在程序运行后,随着时间的推移,编译器逐渐发挥作用,把越来越多的代码编译成本地代码之后,可以获得更高的执行效率
- 当程序运行环境中内存资源限制较大(如部分嵌入式系统中),可以使用解释执行来节约内存;反之,则可以使用编译执行来提升效率。
- 同时,解释器还可以作为编译器(C2才会激进优化)激进优化时的一个“逃生门”,让编译器根据概率选择一些大多数时候都能提升运行速度的优化手段,当激进优化假设不成立。如:加载了新类后,类型继承结构出现变化,出现“罕见陷阱(Uncommon Trap)”时,可以通过逆优化(Deoptimization)退回到解释状态继续执行(部分没有解释器的虚拟机,也会采用不进行激进优化的C1编译器担任“逃生门”的角色)
# 对象的实例化内存布局与访问定位
常见创建对象的方式:
- new
- Class.newInstance
- Contructor.newInstance
- clone
- 反序列化
- 第三方类库
创建对象的步奏
- 判断对象对应的类是否加载,链接,初始化
- 为对象分配内存
- 处理并发安全步奏
- 初始化分配到的空间
- 设置对象的对象头
- 执行init方法进行初始化
对象的内存布局
内容 | 说明 |
---|---|
对象头(Header) | 包含运行时元数据(Mark Word)(元数据里面包含:哈希值,GC分代年龄,锁标志状态,线程持有的锁,偏向线程ID,偏向时间戳),类型指针(指向类元数据InstanceClass,.getClass方法),如果对象是数组还有数组长度 |
实例数据(Instance Data) | 对象真正存储的有效信息,包括各种类型的字段信息 |
对齐补充(Padding) | 没有特殊含义,起到占位符的作用 |
对象的访问定位 栈帧(reference)引用到堆区,堆区指针到方法区类实例信息
对象访问的两种方式
方式 | 说明 |
---|---|
句柄访问 | 在堆中开辟句柄池,池中两个指针:对象实例数据指针指向堆中实例数据,对象类型数据指针指向方法区对象类型数据 |
直接指针(Hotspot) | 直接指向堆中对象实例数据,对象实例数据中包含类型数据指针指向方法区对象类型数据 |
# 字节码指令集
上次更新: 2023/12/18, 13:54:07