解释执行(interperted)
优势在于没有编译等待时间
性能相对差一些
编译执行(complied)
运行效率会高很多,一般认为比解释执行快一个数量级
带来了额外开销
查询运行模式
java -version
-Xint:设置jvm执行模式解释执行模式
-Xcomp:Jvm优先以编译模式运行,不能编译的,以解释模式运行。
-Xmixed:混合模式运行
Hotspot的即时编译器-C1
C1编译器:
是一个简单快速的编译器
主要关注局部性优化
适用于执行时间较短或对启动性能有要求的程序,例如,GUI应用对界面启动速度就有一定要求
也被称为是Client Complier
Hotspot的即时编译器-C2
C2编译器:
是为长期运行的服务端应用程序做性能调优的编译器
适用于执行时间较长或对峰值性能有要求的程序
也被称之为Server Complier
分层编译
0:解释执行
1:简单C1编译,会用C1编译器进行一些简单的优化,不开启Profiling(性能监控)
2:受限的C1编译,仅执行带有方法调用次数以及循环回边执行次数的C1编译
3:完全C1编译,会执行带有所有Profiling的C1代码
4:C2编译,使用C2编译器进行优化,该级别会启用一些编译耗时较长的优化,一些情况下会根据性能监控信息进行一些非常激进的性能优化
级别越高,应用启动越慢,优化开销越高,峰值性能也越高
方法内联
条件:
方法足够小
热点方法:如果方法体小于325字节会尝试内联可用-XX:FreqInlineSize修改大小
非热点方法:如果方法体小于35字节,会尝试内联可用-XX:MaxInlineSize修改大小
被调用方法运行时的实现被可以唯一确定
static方法、private 方法以及final方法,JIT可以唯一确定具体的实现代码
public的实例方法,指向的实现可能是自身、父类、子类的代码,当且仅当JIT唯一确定方法的具体实现时,才有可能完成内联
方法内联可能带来的问题
CodeCache的溢出,导致JVM退化成解释执行模式
内联相关的jvm参数
参数名 | 默认 | 说明 |
---|---|---|
-XX:+PrintInlining | - | 打印内联详情,该参数需要和-XX:+UnlockDiagnosticVMOptions配合使用 |
-XX:+UnlockDiagnosticVMOptions | - | 打印JVM诊断相关的信息 |
-XX:MaxInlineSize=n | 35 | 如果非热点方法的字节码超过该值,则无法内联,单位字节 |
-XX:FreqInlineSize=n | 325 | 如果热点方法的字节码超过该值,则无法内联,单位字节 |
-XX:InlineSmallCode=n | 1000 | 目标编译后生成的机器码代销大于该值无法内联单位字节 |
-XX:MaxInlineLevel=n | 9 | 内联方法的最大调用帧数嵌套调用的最大内联深度 |
-XX:MaxTrivialSize=n | 6 | 如果方法的字节码少于该值,则直接内联,单位字节 |
-XX:MinInliningThreshold=n | 250 | 如果目标方法的调用次数低于该值,则不去内联 |
-XX:LiveNodeCountInliningCutoff=n | 40000 | 编译过程中最大活动字节数(IR节点)的上限,仅对C2编译器有效 |
-XX:InlineFrequencyCount=n | 100 | 如果方法的调用点(call site)的执行次数超过该值,则出发内联 |
-XX:MaxRecursiveInlineLevel | 1 | 递归调用大于这么多次数就不内联 |
-XX:+InlineSynchronizedMethods | 开启 | 是否允许内联同步方法 |