2013-12-11 50 views
5

当我读的书“斯卡拉深度”,它提到的HotSpot编译器有几个重要特征的动态去优化,其中之一就是“动态去优化”:关于热点

这是确定的优化做的能力,事实上,提高性能,并撤消优化,允许他人施加

看来热点会尝试各种各样的“优化”,且选择他们中最好的一个。

但我不太明白。这里的“优化”是否都由HotSpot提供?我的意思是程序员经常尝试用一些技巧来优化代码,HotSpot会处理它们吗?

是否有任何常见的“优化”将HotSpot尝试?

回答

0

“编译器优化”是代码的转换,试图在某种意义上使其更好 - 通常,它需要更少的时间来执行。 Wikipedia article on optimizing compilers有一个很好的通用优化列表; Hotspot JIT编译器可能会完成所有这些和更多。

所以这本书意味着热点将这些技术中的一些应用到代码中,看看它是否改善了运行时间,如果它不会恢复它。

正如您已经正确说明的那样,手动更改代码以使其更好的过程也称为“优化”或“手动优化”。编译器试图尽可能多地应用优化,但许多可能的修改仍然需要手动应用。再次,Wikipedia has a solid article about what a program optimization is

8

HotSpot的优化类型与开发人员在Java源代码级别的不同,尽管其中一些具有相同的净效果。

这是JIT编译器的武器库的一部分:

  • 方法调用内联;
  • 从循环中提取值;
  • 单形呼叫站点;
  • 将对象放置在堆栈上,并进行Escape分析;
  • 绑定变量到CPU寄存器;
  • 锁定elision。

最有趣的部分是一些优化,如之间的协同作用:

  1. 调用点作为单态的实施;
  2. 这允许方法内联;
  3. 它邀请堆栈放置一个对象;
  4. 它允许对象的字段绑定到寄存器。

但是,您的报价是我所知道的最好的错误。优化后的代码不会进行任何自定义分析,因为它会降低速度。去优化的唯一条件是违反了代码进行JIT编译的乐观假设。例如:一个给定的方法调用站点只接收一种类型的对象,专门用于该对象(编译为一个单形调用站点),但之后会出现不同的对象类型。现在优化后的代码无法执行,必须进行优化。

10

Oracle提供了一个(rather concise) summary of this performance techniques applied by the JVM。它解释:

去优化是将优化的堆栈帧更改为 未优化的过程。就编译方法而言,它也是丢弃具有无效乐观优化的代码的过程,并且用较不优化的,更健壮的代码代替它。一种方法可能在 的原理上被去最优化几十次。

在这种总之,去最佳化的原因如下:

  1. 编译器可以存根出尚余分支deoptimize如果曾经采取。
  2. 类似地,历史上从未失败的低级安全检查。
  3. 如果调用站点或类型转换遇到意外类型,编译器会去优化。
  4. 如果某个类被加载使以前的类层次结构分析失效,则任何线程中的任何受影响的方法激活都会被强制 设置为一个安全点并被去最佳化。
  5. 这种间接去优化是由依赖系统调解的。如果编译器做出一个不受检查的假设,则它必须注册一个 可检查依赖项。 (例如,类Foo没有子类,或 方法Foo.bar是没有覆盖。)

就个人而言,我发现this blog entry上微基准相当可读又包括优化和去最佳化的主题在HotSpot VM上。另外,我可以推荐reading through this presentation