Java程序员Java学习笔记

JVM编译优化

2017-08-23  本文已影响109人  GhostStories

欢迎访问我的博客查看原文:http://wangnan.tech

在部分的商用虚拟机中,Java 程序最初是通过解释器(Interpreter )进行解释执行的,当虚拟机发现某个方法或代码块的运行特别频繁的时候,就会把这些代码认定为“热点代码”。为了提高热点代码的执行效率,在运行时,即时编译器(Just In Time Compiler )会把这些代码编译成与本地平台相关的机器码,并进行各种层次的优化。

HotSpot 内的即时编译器

解释器和编译器各有各的优点

HotSpot中内置了两个即时编译器,分别称为 Client Compiler和 Server Compiler ,或者简称为 C1编译器和 C2编译器。

目前的 HotSpot编译器默认的是解释器和其中一个即时编译器配合的方式工作,具体是哪一个编译器,取决于虚拟机运行的模式,HotSpot虚拟机会根据自身版本与计算机的硬件性能自动选择运行模式

用户也可以使用 -client和 -server参数强制指定虚拟机运行在 Client模式或者 Server模式。这种配合使用的方式称为“混合模式”(Mixed Mode)

用户可以使用参数 -Xint 强制虚拟机运行于 “解释模式”(Interpreted Mode),这时候编译器完全不介入工作。

另外,使用 -Xcomp 强制虚拟机运行于 “编译模式”(Compiled Mode),这时候将优先采用编译方式执行,但是解释器仍然要在编译无法进行的情况下接入执行过程。通过虚拟机 -version 命令可以查看当前默认的运行模式。

被编译对象和触发条件

在运行过程中会被即时编译的“热点代码”有两类

对于第一种,编译器会将整个方法作为编译对象,这也是标准的JIT 编译方式。

对于第二种是由循环体出发的,但是编译器依然会以整个方法作为编译对象,因为发生在方法执行过程中,称为栈上替换。

判断一段代码是否是热点代码,是不是需要出发即时编译,这样的行为称为热点探测(Hot Spot Detection),探测算法有两种,分别为。

编译过程

编译期优化(早期优化)

为了保证JRuby,Groovy等语言编译的字节码也能得到性能优化,JVM将性能优化放在了后期的运行时优化,即JIT运行时编译优化中。
具体优化:

  1. 编译期优化主要为语法糖,用来实现Java的各种新的语法特性,比如泛型,变长参数,自动装箱/拆箱。
  2. Java语法糖:与字节码无关,编译后会去掉它们。作用仅仅为方便码农写代码,以及将运行时异常在编译期及早发现(如泛型的使用)。
  3. 泛型与类型擦除
    Java泛型只在编译期存在,编译完成后的字节码中会替换为原生类型。故称Java泛型为伪泛型。C#的泛型在运行期仍然存在。
  4. 条件编译
    if语句中使用常量。比如if(false) {},这个语句块不会被编译到字节码中.这个过程在编译时的控制流分析中完成。

运行时优化(晚期优化)

不同JVM的运行时优化策略
Hotspot采用解释器与编译器并存的构架。
第0层,解释执行,不开启性能监控器,可触发第一层编译
第1层,将字节码编译为机器码,进行简单可靠的优化,可以开启性能监控
第2层,将字节码编译为机器码,会开启一些编译耗时的优化和一些不可靠的激进

具体优化

参考:

欢迎关注我的微信订阅号:



欢迎关注我的开发者头条独家号搜索:269166

上一篇下一篇

猜你喜欢

热点阅读