JVM-JIT优化

Hotspot

热点编译的概念

对于程序来说,通常只有一部分代码被经常执行,这些关键代码被称为应用的热点,执行的越多就认为是越热。将这些代码编译为本地机器特定的二进制码,可以有效提高应用性能。

选择编译器类型

-server,更晚编译,但是编译后的优化更多,性能更高

-client,很早就开始编译

-XX:+TieredCompilation,开启分层编译,可以让jvm在启动时启用client编译,随着代码变热后再转为server编译。

缺省编译器取决于机器位数、操作系统和CPU数目。32位的机器上,一般默认都是client编译,64位机器上一般都是server编译,多核机器一般是server编译。

中的mix mode 一般指编译时机:

-Xint表示禁用JIT,所有字节码都被解释执行,这个模式的速度最慢的。

-Xcomp表示所有字节码都首先被编译成本地代码,然后再执行。

-Xmixed,默认模式,让JIT根据程序运行的情况,有选择地将某些代码编译成本地代码。

-Xcomp和-Xmixed到底谁的速度快,针对不同的程序可能有不同的结果,基本还是推荐用默认模式。

代码缓存相关

 在编译后,会有一个代码缓存保存编译后的代码,一旦这个缓存满了,jvm将无法继续编译代码。

当jvm提示:  CodeCache is full,就表示需要增加代码缓存大小。

–XX:ReservedCodeCacheSize=N可以用来调整这个大小。

编译阈值

代码是否进行编译,取决于代码执行的频度,是否到达编译阈值。

计数器有两种:方法调用计数器和方法里的循环回边计数器 

一个方法是否达到编译阈值取决于方法中的两种计数器之和。编译阈值调整的参数为:-XX:CompileThreshold=N

方法调用计数器统计的并不是方法被调用的绝对次数,而是一个相对的执行频率,即一段时间之内方法被调用的次数。当超过一定的时间限度,如果方法的调用次数仍然不足以让它提交给即时编译器编译,那这个方法的调用计数器就会被减少一半,这个过程称为方法调用计数器热度的衰减(Counter Decay),而这段时间就称为此方法统计的半衰周期(Counter Half Life Time)。进行热度衰减的动作是在虚拟机进行垃圾收集时顺便进行的,可以使用虚拟机参数-XX:-UseCounterDecay来关闭热度衰减,让方法计数器统计方法调用的绝对次数,这样,只要系统运行时间足够长,绝大部分方法都会被编译成本地代码。另外,可以使用-XX:CounterHalfLifeTime参数设置半衰周期的时间,单位是秒。

与方法计数器不同,回边计数器没有计数热度衰减的过程,因此这个计数器统计的就是该方法循环执行的绝对次数。

编译线程

进行代码编译的时候,是采用多线程进行编译的。

方法内联

内联默认开启,-XX:-Inline,可以关闭,但是不要关闭,一旦关闭对性能有巨大影响。

方法是否内联取决于方法有多热和方法的大小,

很热的方法如果方法字节码小于325字节才会内联,这个大小由参数 -XX:MaxFreqInlinesSzie=N 调整,但是这个很热与热点编译不同,没有任何参数可以调整热度。

方法小于35个字节码,一定会内联,这个大小可以通过参数-XX:MaxInlinesSzie=N 调整。

猜你喜欢

转载自blog.csdn.net/qq_42709262/article/details/88540301
JIT