Java JIT什么时候会出现错误的优化?

4
JIT在10k次调用之后进行方法优化(-XX:+PrintCompilation),您可以使用-XX:CompileThreshold进行配置。我读到了不降低此阈值的原因是JIT优化可能是错误的,或者您正在优化不经常使用的代码。我有几个关于这个领域的问题:
  1. 我认为错误的优化(即:on-stack-replacement)是由于多态方法的懒惰类加载导致的。但是在发现3个实现(我认为)之后,JVM只需执行索引表查找。当然,如果您有更多的多态实现,则速度会受到影响。多态方法是错误的JIT优化的唯一原因或主要原因吗?如果不是,还有其他原因吗?
  2. 如果我可以强制在启动时加载所有类,以便JVM可以预先构建这些索引表,那么总体优化是否更好?采用优化全部方法的方法有什么问题?如果我的目标仅是速度,那么成本是多少?
  3. 与C ++相比,如果我的源代码是封闭的,这意味着没有第三方库,就像低延迟系统一样,是否有一种方法可以强制进行预先优化,以使性能更接近C ++?
  4. Peter Lawrey在他的Oracle杂志文章中提到,您可以通过在生产中人为地运行足够的测试数据以满足阈值来启动JIT。这样做似乎在生产环境中很危险,一旦出现差错,您将被解雇。是否有更好的方法可以在最小风险的情况下完成?
  5. 非常感谢任何关于此主题(涉及Java和C ++)的良好参考资料。
更新:#3。永远不应该期望Java比C ++快,只是想接近它。

C和C++的哲学是:“如果你搞砸了,你的代码可能不会做你想要它做的事情”。Java/C#/Python/大多数其他语言则表示:“如果你做错了什么,我会给你一个错误,这样你就可以处理这种情况”。这个非常事实意味着Java本质上比C++做更多的工作 - 在性能敏感的情况下,这可能会产生很大的差异。 - user541686
我怀疑@PeterLawrey真的说过那句话,但我会让他发表评论。 - user207421
您可以通过运行足够的循环来触发JIT。这就是微基准测试的运行方式。Cliff还建议,否则您正在测量错误的内容。 - ying
1个回答

2
有没有一种方法可以强制进行优化,以提高性能,使其比C++更好?
不行。这是Java规范所强制执行的语义和JVM生态系统的工作方式的基本限制,假设实现和代码的质量相同,它将比C ++ 实现更慢。查看我关于这个主题的现有答案获取更多细节。

确实,你不能事先让Java进行优化,但这并不意味着它比C++更慢。也许现在是这样,但这种说法并没有足够的证据来保证未来一定会持续下去。 - Louis Wasserman
@Louis: 这与事先优化无关,而与 JIT 几乎没有运行时间和空间以及语言语义强制使其比较慢有关。我在我的链接答案中详细讨论了这一点。 - Puppy
@DeadMG,你在现有答案中说得很对。我意识到,在评估应用程序时,正确性、延迟和吞吐量是不能分开的。否则我们都需要用汇编语言编程。但是,通过各种优化手段,Java能否接近C++呢? - ying

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