JIT编译有哪些缺点?

5
及时编译具有许多理论优势:它具有更多关于机器、标志状态和代码使用情况的信息。 它允许您在运行之前避免耗时的编译,加快开发周期。
简单地说,JIT编译似乎是一种更好的方法;虽然存在一些开销,但如果足够智能,它可以加速代码以抵消这些开销。
但是,我认为这并不是全部。有哪些理论和实际的缺点呢? 是的,“启动时间较慢”经常被提及,还有“内存消耗增加”,但我想知道是否还有其他方面。
例如,跟踪和JIT编译是否会破坏CPU高速缓存? 如果您的程序很大,并且实际上没有太多特别热门的路径,那么跟踪和JIT可能需要花费更多时间,这是否值得?
似乎有人已经写了一篇关于此或解决JIT固有问题的论文。如果有人有测量数据,那就更好了。
编辑:我正在讨论即时编译与预先编译(可能具有反馈定向优化)相比,而不是与解释相比。

即时编译和预编译相比有哪些优点? - phuclv
3个回答

1
如果JIT正常工作,就没有真正的缺点。话虽如此,由于Hotspot非常复杂,Sun花了很长时间来稳定它。关于基准数据,您可以随时运行以下实验:
运行SPECjbb、SPECjvm或您自己的基准测试,并修改执行java的命令行以包括:
-Xint

这将排除任何运行时编译的发生。


抱歉。当然,一款优秀的JIT肯定比解释执行更好,但我正在谈论的是JIT与AOT编译的区别。 - Kyle C

1
例如,跟踪和JIT编译是否会破坏CPU缓存?如果您的程序很大,并且实际上没有特别热门的路径,那么有没有花费更多时间跟踪和JIT编译比值得的风险?
这是有可能的。但整个优化游戏是在权衡各种因素以实现最佳结果(在平均情况下)。大多数应用程序确实有相对热和冷的路径,即使热路径都在标准类库中。
此外,您实际上正在说这个假设的应用程序根本不值得JIT编译。在这种情况下,“解决方案”就是关闭JIT编译并运行它。
似乎有人已经写了一篇关于此问题或解决JIT固有问题的论文。
你本以为会有的。
但另一方面,建立和维护Oracle、IBM等JVM中的JIT编译器的人可能会因商业原因而被限制告诉世界他们的想法和结果。(发布源代码是一回事,但解释为什么选择特定策略是另一回事。)还有动机的问题。

0

主要问题在于当前的虚拟机必须加载 - 这意味着将整个编译器和运行时加载到内存中,因此速度不会很快。

一旦加载完成,编译和分析可以在长期后台进行,并且理论上可以通过手动优化以适应运行时情况而显着快于任何静态编译语言。 (考虑这样一种情况:一个函数被确定为没有副作用并且不依赖于被调用50次/秒的相同参数的外部数据 - 动态编译语言可以简单地学习返回常量。这是静态编译语言无法通用地实现的。)

请注意,这不一定总是虚拟机的问题,如果它们开始将虚拟机构建到操作系统中并跨多个应用程序重复使用虚拟机,则此问题将消失。

此外,VM字节码倾向于用更少的字节做更多的事情。这就是为什么微软最初在Excel / Word(Java之前)中使用VM的原因,仅仅是为了减小代码大小。

这部分只是猜测,但我认为这意味着自定义CPU可以被优化以更快地运行,因为读写将不再是瓶颈。RISC系统往往假设CPU操作而不是I/O是瓶颈,我不认为这总是正确的——在单个“opcode”中执行更多工作应该意味着CPU制造商有更多机会优化他们的硬件。

我的观点?没有固有的缺点,主要的现实缺点是加载时间。

哦,另一个现实世界的缺点是,Java和C#倾向于在堆上分配所有对象。在C++中,堆分配比栈分配速度快得多,但仍然无法达到栈分配的速度。


简化后,我认为仍然有效(除了虚拟机语言实际上没有“堆”,但它具有相同的净效果,即永久存在的内存 - 同时我比较擅长Java而不是C#,可能C#允许堆栈分配,但我不确定)。 - Bill K

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接