在 C++ 中,我可以声明一个“内联”方法,编译器可能会内联它。据我了解,Java 中没有这样的关键字。
如果 JVM 决定这样做,内联是否完成?我能以某种方式影响这个决定吗?
在 C++ 中,我可以声明一个“内联”方法,编译器可能会内联它。据我了解,Java 中没有这样的关键字。
如果 JVM 决定这样做,内联是否完成?我能以某种方式影响这个决定吗?
其他几个答案表明只能内联最终方法 - 这是不正确的,因为 HotSpot 足够聪明,只要它们还没有被覆盖,就能够内联非最终方法。当加载一个覆盖该方法的类时,它可以撤消其优化。显然,使方法最终意味着永远不需要......
基本上让 JVM 完成它的工作——它可能比你更擅长确定在哪里内联。
您是否有过确信 JVM 做得不好的情况?假设您使用的是 HotSpot,您是否尝试过使用服务器版本而不是客户端?这可以产生巨大的影响。
尽管 java 编译器可以内联(对于简短的早期绑定方法),但真正的内联将由 JIT 编译器完成。JIT (HotSpot) 编译器甚至能够内联虚拟方法。与之交互的最佳方式是编写简单明了的代码。最有可能的是,使用反射的代码不允许内联。
希望有帮助。
'在 C++ 中,我可以声明一个“内联”方法,编译器将内联它' ......或者不。编译器可以自由地使函数内联或不内联,你不能真正影响结果。这只是对编译器的提示。
在 Java 中没有这样的事情,编译器(以及稍后执行优化时的 VM)可以决定“内联”该方法。
请注意,最终方法被内联的机会更大(编译器不能内联非最终方法,因为它们可能在派生类中被覆盖)。使用现代 VM,可以在运行时进行类似的优化。VM 将标记类型(因此它可以执行类型检查)并将内联代码。只有当检查失败时,才会退回到原来未优化的多态方法调用。
如果所讨论的方法是以下情况,则更有可能发生内联:
因为这些是 JVM 可以确定调用效果的唯一情况。
class A {
final int foo() { return 3; }
}
给定这个类,任何对 foo() 的调用都可以用常量“3”代替。任何 Java1 虚拟机都可以做到这一点,因为final关键字明确规定不可能有一个覆盖“int foo()”的子类。
内联该方法在调用站点提供以下好处:
过去,程序员经常为此插入final关键字。或者为了更好地促进内联并提高执行速度,他们会将许多较小的方法组合成一个较大的方法。但在许多方面,这些技术破坏了编程语言内置的模块化和可重用性的整个设施。
现代 JVM,如 Java HotSpot VM,能够在没有final的情况下内联类。关键词**。
( http://java.sun.com/developer/technicalArticles/Networking/HotSpot/inlining.html )
阅读此内容以了解内联行为。 http://www.javacoffeebreak.com/articles/thinkinginjava/comparingc++andjava.html
它说最终方法可以内联,但并非总是如此。
是的,如果 JVM 决定这样做,它可以。影响的方法包括将方法设置为静态或最终的。
当然,最重要的是方法的结构需要内联友好。Short 有帮助,但最重要的是它只需要使用它的局部变量和它的参数,没有字段,以及对同一类中其他方法的最小方法调用。
但是,您不应该过早地进行此类优化,您实际上可能会使事情变得更糟(因为您可能会短路其他潜在的优化)。JVM 有时会意识到可以在没有这些提示的情况下内联方法。
在比较普通函数和最终函数(JVM 称为内联)时,我发现它们之间没有性能提升。也许函数调用的开销已经很低了。
注意:我使用框模糊算法来评估性能。