还记得上次被C开发人员嘲笑的时候吗? Java如此繁琐,以至于他们甚至都不会考虑使用这种语言?
在许多方面,这一概念仍然成立。 但是对于典型的用法(在大型企业的骨干中),Java性能绝对可以与许多竞争者抗衡。 这在很大程度上要归功于神奇的JIT。
在深入解释“即时”编译技巧之前,让我们深入了解一下背景知识。
您可能还记得– Java是一种解释型语言。 大多数用户都知道的Java编译器javac不会像C编译器那样直接将Java源文件编译为处理器指令。 而是生成字节码,这是由规范控制的与机器无关的二进制格式。 JVM在运行时解释该字节码。这是Java在跨平台上如此成功的主要原因-您可以在一个平台上编写和构建程序,然后在其他平台上运行。 另一方面,它确实引入了一些负面方面。 其中最严重的事实之一是,解释的代码通常比直接编译为平台特定的本机二进制代码的代码要慢。 Sun雇用Cliff Click博士提供解决方案时,已经在90年代末意识到了这种严重性。
欢迎– HotSpot 。 该名称源自JVM识别应用程序中“热点”(经常执行的字节代码块)的功能。 然后将它们作为目标,以进行广泛的优化并将其编译为处理器专用指令。 通过优化,可以以最少的开销实现对性能要求较低的代码的高性能执行。 在某些情况下, JVM的自适应优化有可能超过手工编码的C ++或C代码的性能。
JVM中负责这些优化的组件称为即时编译器(JIT)。 它利用了有趣的程序属性。 实际上,所有程序都将大部分时间都花在执行少量代码上。 Java HotSpot VM不会及时编译所有代码,而是立即使用解释器运行程序,并在运行时分析代码以检测程序中的关键热点。 然后,它将全球本地代码优化器的注意力集中在热点上。 通过避免不经常执行的代码的编译,Java HotSpot编译器可以更加关注程序的性能关键部分。 这意味着您的编译时间总体上不会增加。 该热点监视将在程序运行时动态地继续进行,以便根据您的应用程序的使用模式即时调整其性能。
JIT通过多种技术来实现性能优势,例如消除无效代码,绕过边界条件检查,消除冗余负载,内联方法等。
以下示例说明了JIT用来实现更好性能的那些技术。 在第一部分中,有开发人员编写的代码。 在第二个代码段中,是在热点检测到“热点”并应用了优化魔术之后执行的代码:
- 未优化的代码。
class Calculator {Wrapper wrapper;public void calculate() {y = wrapper.get();z = wrapper.get();sum = y + z;} }class Wrapper {final int value;final int get() {return value;} }
- 优化代码
class Calculator {Wrapper wrapper;public void calculate() {y = wrapper.value;sum = y + y;} }class Wrapper {final int value;final int get() {return value;} }
上面的小样本中描述的第一类是开发人员编写的类,第二类是JIT完成工作之后的示例。 该示例包含一些应用的优化技术。 让我们看一下如何达到最终结果:
- 未优化的代码。 这是在被检测为热点之前正在运行的代码:
public void calculate() {y = wrapper.get();z = wrapper.get();sum = y + z; }
- 内联方法。 wrapper.get()已被b.value取代,因为通过直接访问wrapper.value而不是通过函数调用来减少延迟。
public void calculate() {y = wrapper.value;z = wrapper.value;sum = y + z; }
- 卸下多余的负载。 z = wrapper.value已替换为z = y,以便通过访问局部值而不是wrapper.value来减少延迟。
public void calculate() {y = wrapper.value;z = y;sum = y + z; }
- 复制传播。 z = y已由y = y代替,因为没有多余的变量z,因为z和y的值相等。
public void calculate() {y = wrapper.value;y = y;sum = y + y; }
- 消除无效代码。 y = y是不必要的,可以消除。
public void calculate() {y = wrapper.value;sum = y + y; }
这个小样本包含JIT用来提高代码性能的几种强大技术。 希望它对理解这个强大的概念很有帮助。
喜欢这个职位吗? 我们还有很多工作要做。 订阅我们的RSS feed或Twitter流并享受。
本文使用了以下相关链接(两个愤怒的C开发人员除外):
- http://www.oracle.com/technetwork/java/whitepaper-135217.html
- http://www.oracle.com/technetwork/java/javase/tech/index-jsp-136373.html
- http://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/underst_jit.html
参考: 您是否能及时编译? 由我们的JCG合作伙伴 Nikita Salnikov Tarnovski在Plumbr Blog博客上获得。
翻译自: https://www.javacodegeeks.com/2012/12/do-you-get-just-in-time-compilation.html