在Java中内联

CL2*_*L23 36 java jvm inline-method inlining

在C++中,我可以声明一个方法"内联",编译器可能会内联它.据我所知,Java中没有这样的关键字.

如果JVM决定这样做,内联就完成了吗?我能以某种方式影响这个决定吗?

Jon*_*eet 52

一对夫妇的其他答案的建议,只有最后的方法可以被内联-这是不正确的,因为热点是足够聪明,能够内联非最终方法,只要他们还没有被覆盖还没有.当加载一个覆盖该方法的类时,它可以撤消其优化.显然,使方法最终意味着永远不需要......

基本上让JVM完成它的工作 - 它可能会比你更好地计算内联的位置.

您是否认为JVM没有做好工作?假设您正在使用HotSpot,您是否尝试使用服务器版本而不是客户端?这可以产生巨大的差异.

  • 实际上,HotSpot可以内联方法(推测性地),即使它被覆盖,也可以为非预期类型的​​对象虚拟调用方法.Server HotSpot甚至可以内联两个不同版本的方法(双态内联). (29认同)
  • @Tom:请注意我是否在答案中加入了这个内容? (3认同)
  • 好吧,我肯定有热点没有内联和手动内联的案例导致核心处理循环的性能提高5倍. (3认同)

Shi*_*iel 6

尽管java编译器可以进行内联(对于简短的早期绑定方法),但真正的内联将由JIT编译器完成.JIT(HotSpot)编译器甚至可以内联虚拟方法.与之交互的最佳方式是编写简单而简洁的代码.最有可能的是,使用Reflection的代码不允许内联.

希望有所帮助.


Dav*_*eas 5

'在C++中,我可以声明一个"内联"方法,编译器将内联它 ......或者不是.编译器可以自由地使函数内联,也不会影响结果.它只是编译器的一个提示.

在Java中没有这样的东西,编译器(以及稍后执行优化时的VM)可以决定"内联"该方法.

请注意,最终方法更有可能被内联(编译器不能内联非最终方法,因为它们可能会在派生类中被覆盖).使用现代VM,可以在运行时进行类似的优化.VM将标记类型(因此它可以执行类型检查)并将内联代码.只有在检查失败时,它才会回退到原始的未优化的多态方法调用中.

  • 很重要的一点!"inline"不会强制编译器在C中内联您的方法. (2认同)
  • “编译器无法内联非最终方法,因为它们可能会在派生类中被覆盖)” - 完全错误的陈述。如果尚未在运行时覆盖非最终方法,JIT 编译器可以并且确实会内联非最终方法。 (2认同)