目录
上一篇日志讲到使用JIT即使编译方式下代码的执行方式有解释执行和编译执行两种,对于程序中函数的执行,要么是使用解释执行的方式,要么是使用编译执行方式(对于热点代码)编译后得到的机器码执行,这两种方式的切换发生在函数的两次调用间隔,前一次调用时虚拟机没有把这段函数判定为热点代码,后一次调用时发现其是热点代码并且进行了编译,那么就会使用提供的机器码执行。对于大部分的函数执行来说是这样的,但有一些情况例外,如调用次数不多且里面有很多循环操作的函数,举个例子,main()函数里面有一个for循环需要执行1000000次,这种情况下,由于我们的main()只执行一次,不可能被虚拟机判定为热点代码,但是函数体内有一个循环被大量重复执行,按道理来说使用编译执行的方式效率更高,怎么办?
OSR栈上替换
解决上面的问题,虚拟机使用了一种叫OSR(on stack replacement)栈上替换技术,对于函数体内多次循环执行的情况,编译器会记录循环的次数,达到一定的次数后虚拟机就会判定这段代码为热点代码,然后对其即时编译成机器码。