编程语言
首页 > 编程语言> > 深入理解java虚拟机笔记Chapter11

深入理解java虚拟机笔记Chapter11

作者:互联网

运行期优化

即时编译

什么是即时编译?

HotSpot 虚拟机内的即时编译器运作过程

我们主要通过以下 5 个问题来了解 HotSpot 虚拟机的即时编译器。

为什么要使用解释器与编译器并存的架构?

为什么虚拟机要实现两个不同的 JIT 编译器?

什么是虚拟机的分层编译?

分层编译就是根据编译器编译、优化的规模与耗时,划分出不同的编译层次,在代码运行的过程中,可以动态的选择将某一部分代码片段提升一个编译层次或者降低一个编译层次。

C1 与 C2 编译器会同时工作,许多代码可能会被多次编译。

目的: 在程序的启动响应时间和运行效率间达到平衡。

编译层次的划分:

如何判断热点代码,触发编译?

1、什么是热点代码?

我们发现,判断热点代码的一个要点就是: 多次执行 。那么虚拟机是如何知道一个方法或者一个循环体被多次执行的呢?

2、什么是 “多次” 执行?

2.1、HotSpot 中每个方法的 2 个计数器

2.2、HotSpot 热点代码探测流程

热点代码编译的过程?

虚拟机在代码编译未完成时会按照解释方式继续执行,编译动作在后台的编译线程执行。

禁止后台编译:-XX: -BackgroundCompilation,打开后这个开关参数后,交编译请求的线程会等待编译完成,然后执行编译器输出的本地代码。

经典优化技术介绍

公共子表达式消除【语言无关】

如果一个表达式 E 已经计算过了,并且从先前的计算到现在,E 中所有变量值都没有发生变化,则 E 为公共子表达式,无需再次计算,直接用之前的结果替换。

举例

有表达式int d = (c * b) * 12 + a + (a + b * c),这段代码交给Javac编译器不会进行任何优化。

当这段代码进入到虚拟机即时编译器后,编译器检测到c * b和b * c是一样的表达式,因此这条公式变为int d = E * 12 + a + (a + E)

还可能变为int d = E * 13 + a * 2

数组范围检查消除【语言相关】

在循环中使用循环变量访问数组,如果可以判断循环变量的范围在数组的索引范围内,则可以消除整个循环的数组范围检查

方法内联【最重要】

目的是:去除方法调用的成本(如建立栈帧等),并为其他优化建立良好的基础,所以一般将方法内联放在优化序列最前端,因为它对其他优化有帮助。

类型继承关系分析(Class Hierarchy Analysis,CHA):用于确定在目前已加载的类中,某个接口是否有多于一种的实现,某个类是否存在子类、子类是否为抽象类等。

逃逸分析【最前沿】

基本行为

分析对象的作用域,看它有没有能在当前作用域之外使用:

对于不会逃逸到方法或线程外的对象能进行优化

虚拟机参数

优化案例

原始代码:

static class B {
    int value;
    final int get() {
        return value;
    }
}

public void foo() {
y = b.get();
// ...do stuff...
z = b.get();
sum = y + z;
}

第一步优化: 方法内联(一般放在优化序列最前端,因为对其他优化有帮助)

目的:

第二步优化: 公共子表达式消除

public void foo() {
    y = b.value;
    // ...do stuff...  // 因为这部分并没有改变 b.value 的值
                       // 如果把 b.value 看成一个表达式,就是公共表达式消除
    z = y;             // 把这一步的 b.value 替换成 y
    sum = y + z;
}

第三步优化: 复写传播

public void foo() {
    y = b.value;
    // ...do stuff...
    y = y;             // z 变量与以相同,完全没有必要使用一个新的额外变量
                       // 所以将 z 替换为 y
    sum = y + z;
}

第四步优化: 无用代码消除

无用代码:

  1. 永远不会执行的代码
  2. 完全没有意义的代码
public void foo() {
    y = b.value;
    // ...do stuff...
    // y = y; 这句没有意义的,去除
    sum = y + y;
}

标签:调用,java,虚拟机,编译,编译器,Chapter11,方法,代码
来源: https://www.cnblogs.com/kylinxxx/p/13781191.html