java Just in Time Compilation和On Stack Replacement的区别

n9vozmp4  于 2023-06-04  发布在  Java
关注(0)|答案(3)|浏览(193)

他们两个几乎做同样的事情。确定该方法是热的,并编译它而不是解释它。使用OSR,您只需在编译后立即移动到编译版本,而不像JIT,在JIT中,当第二次调用方法时,将调用编译的代码。
除此之外,还有其他的区别吗?

y0u0uwnf

y0u0uwnf1#

一般来说,* 即时 * 编译是指在运行时编译本机代码并执行它,而不是(或除了)解释。有些虚拟机,如Google V8,甚至没有解释器;他们JIT编译每一个被执行的函数(有不同程度的优化)。
栈上替换(On Stack Replacement,OSR)是一种在同一函数的不同实现之间切换的技术。例如,您可以使用OSR在编译完成后立即从解释的或未优化的代码切换到JIT代码。
OSR在函数运行时将其标识为“热”的情况下非常有用。这可能不一定是因为函数被频繁调用;它可能只被调用一次,但它在一个大循环中花费了大量时间,这可以从优化中受益。当OSR发生时,VM被暂停,并且目标函数的堆栈帧被替换为可能在不同位置具有变量的等效帧。
OSR也可以发生在另一个方向:从优化代码到未优化代码或解释代码。优化的代码可以基于过去的行为对程序的运行时行为做出一些假设。例如,如果您只见过一种类型的接收器对象,则可以将虚拟或动态方法调用转换为静态调用。如果后来证明这些假设是错误的,OSR可以用来退回到更保守的实现:优化的堆栈帧被转换成未优化的堆栈帧。如果VM支持内联,您甚至可能最终将优化的堆栈帧转换为 * 几个 * 未优化的堆栈帧。

mzmfm0qo

mzmfm0qo2#

是的,差不多就是这样。Just-in-time compilation可以通过将字节码的“热点”(已知/假定经常执行的字节码的点)编译为本机指令来提高性能。On-Stack Replacement补充了JIT功能,它在编译版本可用时将长时间运行的解释“热”字节码替换为编译版本。上面提到的On-Stack Replacement article展示了一个很好的例子,在这个例子中,如果没有OSR,JIT编译就不会很有用。

fruv7luv

fruv7luv3#

JIT只是..查找方法调用的数量,如果它超过阈值,(-XX:CompileThreshold=)它将编译(到机器码/本机)并缓存该方法。在下一次调用时,将调用已编译的版本。
OSR很有趣。假设一个巨大的for循环在解释模式下运行。JVM决定在某个时间点编译,当它已经越过编译阈值时。因此,当循环仍在运行时,其解释版本可以在代码仍在运行时被编译为本机版本的代码替换!
所以基本上它就是它所说的。将仍在堆栈上运行的解释代码替换为编译代码。
这也可能导致一个有趣但良性的问题,称为“谁吃了我的变量”。参见who ate my variable

相关问题