为什么不JVM编译代码的JVMcaching?
Sun的规范JVM实现将一些非常复杂的优化应用于字节码,以在代码运行几次之后获得接近本地的执行速度。
问题是,为什么这个编译后的代码不能被caching到磁盘上,以便在以后使用同一个函数/类时使用呢?
就目前而言,每次执行程序时,JIT编译器都会重新启动,而不是使用预编译版本的代码。 当字节码基本上被解释时,不会添加这个function会大大增加程序的初始运行时间?
没有采取切断@MYYN发布的链接的方式,我怀疑这是因为JVM执行的优化不是静态的,而是基于数据模式和代码模式的dynamic。 在应用程序的生命周期中,这些数据模式很可能会发生变化,导致caching的优化不够理想。
所以你需要一个机制来确定保存的优化是否仍然是最优化的,在这一点上,你可能会重新优化。
Oracle的JVM确实被logging下来 – 引用Oracle,
编译器可以利用Oracle JVM的类parsing模型来select性地在数据库调用,会话或实例中持久化已编译的Java方法。 当知道Java代码在语义上没有改变时,这样的持久性避免了会话或实例之间不必要的重新编译的开销。
我不知道为什么所有复杂的VM实现都不提供类似的选项。
更新到现有的答案 – Java 8有一个JEP致力于解决这个问题:
=> JEP 145:caching编译代码 。 新的链接 。
在很高的层面上,其明确的目标是 :
保存并重用以前运行的编译本机代码,以便提高大型Java应用程序的启动时间。
希望这可以帮助。
Excelsior JET自2001年发布2.0版以来,已经有了一个cachingJIT编译器。此外,它的AOT编译器可以使用所有优化将caching重新编译为单个DLL /共享对象。
我不知道实际的原因,也没有以任何方式参与JVM实现,但我可以想到一些合理的:
- Java的想法是成为一次写入一次运行的任何地方的语言,把预编译的东西放入类文件是违反的(只有“类”,因为当然实际的字节码仍然在那里)
- 这会增加类文件的大小,因为你会有相同的代码多次,尤其是如果你碰巧在多个不同的JVM下运行相同的程序(这并不罕见,当你认为不同的版本是不同的JVM,你真的要做)
- 类文件本身可能不是可写的(尽pipe检查它会很容易)
- JVM优化部分基于运行时信息,在其他运行中,它们可能不适用(尽pipe它们应该仍然提供一些好处)
但是我真的在猜测,正如你所看到的,我并不认为我的任何理由都是真正的阻挡者。 我认为Sun并不认为这种支持是重中之重,也许我的第一个理由接近事实,因为习惯性地这样做也可能导致人们认为Java类文件真的需要为每个VM分别版本而不是跨平台的。
我最喜欢的方式实际上是有一个单独的字节码到本机的转换器,你可以用它来事先做这样的事情,创build为特定的虚拟机显式构build的类文件,并且可能包含原始的字节码,这样你也可以和不同的虚拟机一起运行。 但是,这可能来自我的经验:我一直在做Java ME,它真的很伤害Java编译器不聪明的编译。