为什么JVM没有缓存JIT编译代码?

Chi*_*chi 106 java jit caching jvm compilation

Sun的规范JVM实现将一些非常复杂的优化应用于字节码,以便在代码运行几次后获得接近本机的执行速度.

问题是,为什么这个编译的代码没有缓存到磁盘上以便在后续使用同一个函数/类时使用?

就目前而言,每次执行程序时,JIT编译器都会重新启动,而不是使用预编译版本的代码.当字节码基本上被解释时,不会添加此功能会大大增加程序的初始运行时间吗?

Ale*_*lli 25

事实证明Oracle的JVM是这样做的 - 引用Oracle,

编译器可以利用Oracle JVM的类解析模型来选择性地跨数据库调用,会话或实例持久保存已编译的Java方法.当已知在语义上Java代码没有改变时,这种持久性避免了跨会话或实例的不必要的重新编译的开销.

我不知道为什么所有复杂的VM实现都不提供类似的选项.

  • 请注意,此Oracle JVM是Oracle数据库中的一个,而不是Oracle在购买Sun时获得的下载. (9认同)
  • 因为其他复杂的JVM没有一个很好的企业RDBMS方便存储的东西:) (7认同)

ska*_*man 25

如果不采用@MYYN发布的链接的'cut'n'paste,我怀疑这是因为JVM执行的优化不是静态的,而是动态的,基于数据模式和代码模式.这些数据模式可能会在应用程序的生命周期中发生变化,从而使缓存的优化不是最佳的.

因此,您需要一种机制来确定保存的优化是否仍然是最优的,此时您可以在运行时重新进行优化.

  • 为什么不将存储的优化作为起点,使用以前运行中学到的东西?从那里JIT可以像往常一样重新优化.在关闭时,该代码可以再次保留,并在下一次运行中用作新的起点. (9认同)
  • ...或者你可以提供持久性作为*选项*,就像Oracle的JVM一样 - 让*高级程序员*能够在他们只是**知道的时间和地点优化他们的应用程序的性能**模式不会**变化,在他们的责任下.为什么不?! (6认同)
  • 因为它可能不值得.如果SUN,IBM和BEA都认为它们的性能JVM不值得,那么它就有充分的理由.也许他们的RT优化比Oracle快,这就是Oracle缓存它的原因. (2认同)
  • 我个人比较喜欢“在运行之间保留 JIT 分析信息”选项,并带有所有警告“这仅对完全相同的 JVM、相同的数据等有效,否则将被忽略”。至于为什么没有实现这一点,我认为持久化和验证 JIT 种子数据所增加的复杂性太大,无法从其他项目中获取资源。考虑到在这个和 Java 8 lambda+streams 之间进行选择,我宁愿选择后者。 (2认同)

Eug*_*gen 14

更新到现有答案 - Java 8有一个致力于解决此问题的JEP:

=> JEP 145:缓存编译代码.新链接.

在很高的层面上,其既定目标是:

保存并重用以前运行的已编译本机代码,以便缩短大型Java应用程序的启动时间.

希望这可以帮助.

  • 该功能尚未[最终版本](http://openjdk.java.net/projects/jdk8/features). (3认同)
  • 断链.--- (2认同)

Dmi*_*kov 5

Excelsior JET在2001年发布的版本2.0之后有一个缓存JIT编译器.此外,它的AOT编译器可以使用所有优化将缓存重新编译为单个DLL /共享对象.

  • 是的,但问题是关于规范的JVM,即Sun的JVM.我很清楚Java有几个AOT编译器以及其他缓存JVM. (3认同)