概述
- 执行引擎的作用是将字节码指令翻译或编译为可以直接在机器执行的机器指令
- 具体执行过程是根据pc寄存器获取字节码指令并执行
- 基本概念
- 机器码(机器语言):二进制编码表示的指令,可直接被硬件执行
- 指令:特定机器码的组合,方便记忆
- 指令集:指令的集合,与特定支持的硬件相关
- 汇编语言:简单来讲就是将指令通过各种助记符来代替,描述一段完整的操作。不过最终还是要翻译为指令才能执行
- 高级语言:更接近人类的语言
- 字节码:特殊状态的二进制编码,目的是跨平台
组成结构
- 解释器:在运行时将pc寄存器指定的字节码逐行解释为机器码执行
- 字节码解释器:就是逐条翻译
- 模板解释器:字节码与模板函数关联,有函数产生机器指令,效率高
- JIT编译器(即时编译器):将源代码直接编译为机器语言
- 编译后的代码缓存会放在方法区
- 垃圾回收
解释器
- 为什么hotspot还保留?
- 优点:程序启动后可以立即执行,缩短启动等待时间
- 冷机与热机的负载差异
- 冷机:程序刚启动时为冷机状态,此时热点代码并未编译成机器代码,并不能承载热机状态下的流量
- 热机:程序启动并运行了很长时间,热点代码已经编译为机器码,可以叫高效率执行,能承载较高流量
JIT编译器
编译器分类
- 前端编译器:将高级语言编译为中间态,去javac编译java为class
- 运行时编译器:将字节码编译为机器码,如JIT编译器将字节码指令编译为机器码指令
- 提前编译器:直接将高级语言编译为机器码指令,如AOT编译器GCJ
热点代码探测
使用频繁的代码可以确定为热点代码,热点代码交给即时编译器编译为机器码指令
- 热点代码:主要是针对执行频率较高的方法或者循环体
- 栈上替换:被编译后的热点代码将替换栈上执行中的代码,这个过程称为栈上替换
- 热点探测方式:基于计数器的探测方式
- 方法调用计数器:针对方法计数,默认client模式是1500,service模式是10000,可以通过虚拟机参数修改-XX:CompileThreshold
- 回边计数器:针对循环体计数
热度衰减
默认情况下热点探测计数并不是统计绝对值,而是统计一段时间内计数有没有达到阀值,超过一定时间还未达到则计数器数值将减少一半,这个过程称为热度衰减。
这段时间称为半衰周期
- 关闭热度衰减:可通过-XX:UseCounterDecat设置
- 设置半衰周期时间:可通过-XX:CounterHalfLifeTime设置,单位秒
相关设置
编译模式设置
- 只解释器:-Xint
- 只编译器:-Xcomp
- 混合模式:-Xmixed
JIT分类设置
可以通过启动参数切换,64位系统默认server
- client模式:编译速度更快
- 方法内联:引用方法代码直接编译到引用位置
- 去虚拟化:对唯一的实现类进行内联
- 冗余消除
- server模式:代码执行效率更高
- 标量替换:用标量值代替复杂对象的属性值
- 栈上分配:未逃逸对象直接分配栈上
- 同步消除:消除不会出现同步问题的同步锁
其它编译器
Graal编译器
目前还处在实验阶段可通过参数开启
AOT编译器
静态编译器,直接将高级语言编译为机器语言
Jdk9中引入实验性AOT编译工具jaotc
- 优点:启动速度快,像c一样提前编译好
- 缺点:破坏了跨平台特性
版权声明:本文为博主原创文章,欢迎转载,转载请注明作者、原文超链接,感谢各位看官!!!
本文出自:monkeyGeek
座右铭:生于忧患,死于安乐
欢迎志同道合的朋友一起交流、探讨!
