Java JIT编译的缺点是什么?

Java JIT编译的缺点是什么?,java,jit,Java,Jit,即时编译在理论上有很多优点:它有更多关于机器、标志状态和代码使用方式的信息。 它允许您在运行之前避免耗时的编译,从而加快开发周期 简单地说,JIT编译似乎是一种优越的方法;有一些开销,但如果足够聪明,它可以加速代码,足以抵消这一点 然而,我认为这不是全部。理论和实践的缺点是什么? 是的,“较慢的启动时间”和“增加的内存消耗”经常被提及,但是 我不知道是否还有更多 例如,跟踪和JIT编译是否会破坏cpu缓存? 如果您的程序很大,并且没有很多特别热门的路径,那么是否存在花费太多时间进行跟踪和JIT的

即时编译在理论上有很多优点:它有更多关于机器、标志状态和代码使用方式的信息。 它允许您在运行之前避免耗时的编译,从而加快开发周期

简单地说,JIT编译似乎是一种优越的方法;有一些开销,但如果足够聪明,它可以加速代码,足以抵消这一点

然而,我认为这不是全部。理论和实践的缺点是什么? 是的,“较慢的启动时间”和“增加的内存消耗”经常被提及,但是 我不知道是否还有更多

例如,跟踪和JIT编译是否会破坏cpu缓存? 如果您的程序很大,并且没有很多特别热门的路径,那么是否存在花费太多时间进行跟踪和JIT的风险

似乎有人写过一篇关于这一点或解决JIT固有问题的论文。如果有人有测量,那就更好了


编辑:我说的是即时编译与提前编译(可能是反馈导向优化)相比,而不是与解释相比。

如果JIT工作正常,就没有真正的缺点。话虽如此,太阳花了很长时间来稳定热点,因为它极其复杂。关于基准数据,您始终可以运行以下实验:

运行SPECjbb、SPECjvm或您自己的基准测试,并修改执行
java
的命令行以包括:

-Xint

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

主要问题是当前VM必须加载—这是将整个编译器和运行时加载到内存中,因此不会很快

一旦加载,编译和分析就可以长期在后台完成,理论上比任何静态编译语言都要快得多,只需手动优化以适应运行时的情况。(想象一下这样一种情况:函数被确定为没有副作用,并且不依赖外部数据,这些数据以相同的参数每秒被调用50次——动态编译语言可以简单地学习返回常量。这是静态编译语言一般无法做到的。)

请注意,这不一定总是VM的问题,如果他们开始将VM构建到操作系统中,并跨多个应用程序重用VM,这个问题就会消失

此外,vm字节码往往用更少的字节做更多的事情。这就是为什么微软最初在Excel/Word(java之前)中使用虚拟机,只是为了减少代码大小

这部分只是猜测,但我认为这意味着可以优化定制CPU以更快地运行,因为读/写不会成为瓶颈。RISC系统倾向于认为CPU操作而不是I/O是瓶颈,我不相信这总是正确的——在一个“操作码”中做更多的工作应该意味着CPU制造商有更多的机会优化他们的硬件

我的观点?没有天生的缺点,现实世界中的主要缺点是加载时间

哦,另一个现实世界的缺点是,Java和C倾向于分配堆上的所有对象。在C++ java中,堆分配比C++快得多,但仍然无法达到栈分配速度。 例如,跟踪和JIT编译是否会破坏cpu缓存?如果您的程序很大,并且没有很多特别热门的路径,那么是否存在花费太多时间进行跟踪和JIT的风险

这是有道理的。但整个优化博弈是权衡各种因素,以在平均情况下获得最佳结果。大多数应用程序都有相对的热路径和冷路径,即使热路径都在标准类库中

此外,您实际上是在说,这个假设的应用程序根本不值得JIT编译。在这种情况下,“修复”将是在禁用JIT编译的情况下运行它

似乎有人写过一篇关于这一点或解决JIT固有问题的论文

你会这么想的


但另一方面,在Oracle、IBM等JVM中构建和维护JIT编译器的人员可能会受到限制,无法向全世界讲述他们的想法和结果。。。出于商业原因。(发布源代码是一回事,但解释他们为什么选择特定策略是另一回事。)还有动机问题。

对不起。当然,好的JIT肯定比解释的要好,但我说的是JIT与AOT编译。简化了,但我认为仍然有效(除了VM语言实际上没有“堆”这一事实),但这是相同的净效应,内存永远挂起——而且我在Java方面比C更好,可能是C允许堆栈分配,我不知道)。