运行期优化

    xiaoxiao2024-07-27  9

    运行期优化——即时编译器—JIT编译器—Just In Time

    执行引擎

    通过类装载器装载的,被分配到JVM的运行时数据区的字节码会被执行引擎执行。执行引擎以指令为单位读取Java字节码。它就像一个CPU一样,一条一条地执行机器指令。每个字节码指令都由一个1字节的操作码和附加的操作数组成。执行引擎取得一个操作码,然后根据操作数来执行任务,完成后就继续执行下一条操作码。

     

    不过Java字节码是用一种人类可以读懂的语言编写的,而不是用机器可以直接执行的语言。因此,执行引擎必须把字节码转换成可以直接被JVM执行的语言。字节码可以通过以下两种方式转换成合适的语言。

    Ø 解释器:一条一条地读取,解释并且执行字节码指令。因为它一条一条地解释和执行指令,所以它可以很快地解释字节码,但是执行起来会比较慢。这是解释执行的语言的一个缺点。字节码这种“语言”基本来说是解释执行的。

     

    Ø 即时编译器:被引入用来弥补解释器的缺点。执行引擎首先按照解释执行的方式来执行,然后在合适的时候,即时编译器把整段字节码编译成本地代码。然后,执行引擎就没有必要再去解释执行方法了,它可以直接通过本地代码去执行它。执行本地代码比一条一条进行解释执行的速度快很多。编译后的代码可以执行的很快,因为本地代码是保存在缓存里的。

    执行引擎执行策略:

    默认设置下,执行引擎并不会同步等待编译请求完成,而是继续进入解释器按照解释方式执行字节码,直到提交的请求被编译器编译完成。当编译工作完成之后,这个方法的调用入口地址就会被系统自动改写成新的地址,下一次调用该方法时就会使用已编译的版本。也就是说,在编译器还未完成之前,执行引擎仍按照解释方式继续执行,而编译动作则在后台的编译线程中进行。

     

    注:JIT编译器来编译代码所花的时间要比用解释器去一条条解释执行花的时间要多。因此,如果代码只被执行一次的话,那么最好还是解释执行而不是编译后再执行。因此,内置了JIT编译器的JVM都会检查方法的执行频率,如果一个方法的执行频率超过一个特定的值的话,那么这个方法就会被编译成本地代码。

     

    判断一段代码是否是热点代码的方式(热点探测)有两种:

    1.基于采样的热点探测:

    此方法会周期性检查各个线程的栈顶,如果发现某个或某些方法经常出现在栈顶,那么这个方法就是热点方法。此方法的缺点是很难精确地确认一个方法的热度,容易受到诸如线程阻塞等因素影响。

    2.基于计数器的热点探测:

    此方法会为每个方法甚至是代码块建立计数器,统计方法的执行次数,如果执行次数超过一个阀值就认为它是热点方法。

    转载请注明原文地址: https://ju.6miu.com/read-1291081.html
    最新回复(0)